@fluidframework/container-utils
Advanced tools
Comparing version 2.0.0-dev.2.3.0.115467 to 2.0.0-dev.3.1.0.125672
@@ -7,12 +7,10 @@ /*! | ||
module.exports = { | ||
"extends": [ | ||
require.resolve("@fluidframework/eslint-config-fluid"), "prettier" | ||
], | ||
"parserOptions": { | ||
"project": ["./tsconfig.json", "./src/test/tsconfig.json"] | ||
}, | ||
"rules": { | ||
"@typescript-eslint/no-non-null-assertion": "off", | ||
"@typescript-eslint/strict-boolean-expressions": "off", | ||
} | ||
} | ||
extends: [require.resolve("@fluidframework/eslint-config-fluid/minimal"), "prettier"], | ||
parserOptions: { | ||
project: ["./tsconfig.json", "./src/test/tsconfig.json"], | ||
}, | ||
rules: { | ||
"@typescript-eslint/no-non-null-assertion": "off", | ||
"@typescript-eslint/strict-boolean-expressions": "off", | ||
}, | ||
}; |
@@ -6,5 +6,5 @@ /*! | ||
'use strict'; | ||
"use strict"; | ||
const getFluidTestMochaConfig = require('@fluidframework/mocha-test-setup/mocharc-common'); | ||
const getFluidTestMochaConfig = require("@fluidframework/mocha-test-setup/mocharc-common"); | ||
@@ -11,0 +11,0 @@ const packageDir = __dirname; |
{ | ||
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", | ||
"extends": "@fluidframework/build-common/api-extractor-common-report.json" | ||
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", | ||
"extends": "@fluidframework/build-common/api-extractor-common-report.json" | ||
} |
@@ -107,7 +107,10 @@ "use strict"; | ||
static wrapIfUnrecognized(originalError, dataProcessingCodepath, sequencedMessage) { | ||
const props = Object.assign({ dataProcessingError: 1, dataProcessingCodepath }, (sequencedMessage === undefined ? undefined : (0, exports.extractSafePropertiesFromMessage)(sequencedMessage))); | ||
const props = Object.assign({ dataProcessingError: 1, dataProcessingCodepath }, (sequencedMessage === undefined | ||
? undefined | ||
: (0, exports.extractSafePropertiesFromMessage)(sequencedMessage))); | ||
const normalizedError = (0, telemetry_utils_1.normalizeError)(originalError, { props }); | ||
// Note that other errors may have the NORMALIZED_ERROR_TYPE errorType, | ||
// but if so they are still suitable to be wrapped as DataProcessingError. | ||
if ((0, telemetry_utils_1.isExternalError)(normalizedError) || normalizedError.errorType === telemetry_utils_1.NORMALIZED_ERROR_TYPE) { | ||
if ((0, telemetry_utils_1.isExternalError)(normalizedError) || | ||
normalizedError.errorType === telemetry_utils_1.NORMALIZED_ERROR_TYPE) { | ||
// Create a new DataProcessingError to wrap this external error | ||
@@ -114,0 +117,0 @@ const dataProcessingError = (0, telemetry_utils_1.wrapError)(normalizedError, (message) => new DataProcessingError(message)); |
@@ -8,3 +8,3 @@ /*! | ||
export declare const pkgName = "@fluidframework/container-utils"; | ||
export declare const pkgVersion = "2.0.0-dev.2.3.0.115467"; | ||
export declare const pkgVersion = "2.0.0-dev.3.1.0.125672"; | ||
//# sourceMappingURL=packageVersion.d.ts.map |
@@ -11,3 +11,3 @@ "use strict"; | ||
exports.pkgName = "@fluidframework/container-utils"; | ||
exports.pkgVersion = "2.0.0-dev.2.3.0.115467"; | ||
exports.pkgVersion = "2.0.0-dev.3.1.0.125672"; | ||
//# sourceMappingURL=packageVersion.js.map |
@@ -99,7 +99,10 @@ /*! | ||
static wrapIfUnrecognized(originalError, dataProcessingCodepath, sequencedMessage) { | ||
const props = Object.assign({ dataProcessingError: 1, dataProcessingCodepath }, (sequencedMessage === undefined ? undefined : extractSafePropertiesFromMessage(sequencedMessage))); | ||
const props = Object.assign({ dataProcessingError: 1, dataProcessingCodepath }, (sequencedMessage === undefined | ||
? undefined | ||
: extractSafePropertiesFromMessage(sequencedMessage))); | ||
const normalizedError = normalizeError(originalError, { props }); | ||
// Note that other errors may have the NORMALIZED_ERROR_TYPE errorType, | ||
// but if so they are still suitable to be wrapped as DataProcessingError. | ||
if (isExternalError(normalizedError) || normalizedError.errorType === NORMALIZED_ERROR_TYPE) { | ||
if (isExternalError(normalizedError) || | ||
normalizedError.errorType === NORMALIZED_ERROR_TYPE) { | ||
// Create a new DataProcessingError to wrap this external error | ||
@@ -106,0 +109,0 @@ const dataProcessingError = wrapError(normalizedError, (message) => new DataProcessingError(message)); |
@@ -8,3 +8,3 @@ /*! | ||
export declare const pkgName = "@fluidframework/container-utils"; | ||
export declare const pkgVersion = "2.0.0-dev.2.3.0.115467"; | ||
export declare const pkgVersion = "2.0.0-dev.3.1.0.125672"; | ||
//# sourceMappingURL=packageVersion.d.ts.map |
@@ -8,3 +8,3 @@ /*! | ||
export const pkgName = "@fluidframework/container-utils"; | ||
export const pkgVersion = "2.0.0-dev.2.3.0.115467"; | ||
export const pkgVersion = "2.0.0-dev.3.1.0.125672"; | ||
//# sourceMappingURL=packageVersion.js.map |
{ | ||
"name": "@fluidframework/container-utils", | ||
"version": "2.0.0-dev.2.3.0.115467", | ||
"version": "2.0.0-dev.3.1.0.125672", | ||
"description": "Fluid container utils", | ||
@@ -32,4 +32,4 @@ "homepage": "https://fluidframework.com", | ||
"format": "npm run prettier:fix", | ||
"lint": "npm run eslint", | ||
"lint:fix": "npm run eslint:fix", | ||
"lint": "npm run prettier && npm run eslint", | ||
"lint:fix": "npm run prettier:fix && npm run eslint:fix", | ||
"prettier": "prettier --check . --ignore-path ../../../.prettierignore", | ||
@@ -69,18 +69,18 @@ "prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore", | ||
"@fluidframework/common-utils": "^1.0.0", | ||
"@fluidframework/container-definitions": ">=2.0.0-dev.2.3.0.115467 <2.0.0-dev.3.0.0", | ||
"@fluidframework/container-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0", | ||
"@fluidframework/protocol-definitions": "^1.1.0", | ||
"@fluidframework/telemetry-utils": ">=2.0.0-dev.2.3.0.115467 <2.0.0-dev.3.0.0" | ||
"@fluidframework/telemetry-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0" | ||
}, | ||
"devDependencies": { | ||
"@fluid-tools/build-cli": "^0.7.0", | ||
"@fluid-tools/build-cli": "^0.8.0", | ||
"@fluidframework/build-common": "^1.1.0", | ||
"@fluidframework/build-tools": "^0.7.0", | ||
"@fluidframework/container-utils-previous": "npm:@fluidframework/container-utils@2.0.0-internal.2.2.0", | ||
"@fluidframework/eslint-config-fluid": "^1.2.0", | ||
"@fluidframework/mocha-test-setup": ">=2.0.0-dev.2.3.0.115467 <2.0.0-dev.3.0.0", | ||
"@fluidframework/test-runtime-utils": ">=2.0.0-dev.2.3.0.115467 <2.0.0-dev.3.0.0", | ||
"@fluidframework/build-tools": "^0.8.0", | ||
"@fluidframework/container-utils-previous": "npm:@fluidframework/container-utils@2.0.0-internal.3.0.0", | ||
"@fluidframework/eslint-config-fluid": "^2.0.0", | ||
"@fluidframework/mocha-test-setup": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0", | ||
"@fluidframework/test-runtime-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0", | ||
"@microsoft/api-extractor": "^7.22.2", | ||
"@rushstack/eslint-config": "^2.5.1", | ||
"@types/mocha": "^9.1.1", | ||
"@types/node": "^14.18.0", | ||
"@types/node": "^14.18.36", | ||
"concurrently": "^6.2.0", | ||
@@ -97,7 +97,8 @@ "copyfiles": "^2.4.1", | ||
"typeValidation": { | ||
"version": "2.0.0-internal.2.3.0", | ||
"baselineRange": ">=2.0.0-internal.2.2.0 <2.0.0-internal.2.3.0", | ||
"baselineVersion": "2.0.0-internal.2.2.0", | ||
"version": "2.0.0-internal.3.1.0", | ||
"previousVersionStyle": "~previousMinor", | ||
"baselineRange": ">=2.0.0-internal.3.0.0 <2.0.0-internal.3.1.0", | ||
"baselineVersion": "2.0.0-internal.3.0.0", | ||
"broken": {} | ||
} | ||
} |
253
src/error.ts
@@ -7,16 +7,16 @@ /*! | ||
import { | ||
ContainerErrorType, | ||
IGenericError, | ||
IErrorBase, | ||
IThrottlingWarning, | ||
IUsageError, | ||
ContainerErrorType, | ||
IGenericError, | ||
IErrorBase, | ||
IThrottlingWarning, | ||
IUsageError, | ||
} from "@fluidframework/container-definitions"; | ||
import { | ||
LoggingError, | ||
IFluidErrorBase, | ||
normalizeError, | ||
wrapError, | ||
wrapErrorAndLog, | ||
isExternalError, | ||
NORMALIZED_ERROR_TYPE, | ||
LoggingError, | ||
IFluidErrorBase, | ||
normalizeError, | ||
wrapError, | ||
wrapErrorAndLog, | ||
isExternalError, | ||
NORMALIZED_ERROR_TYPE, | ||
} from "@fluidframework/telemetry-utils"; | ||
@@ -30,18 +30,14 @@ import { ITelemetryLogger, ITelemetryProperties } from "@fluidframework/common-definitions"; | ||
export class GenericError extends LoggingError implements IGenericError, IFluidErrorBase { | ||
readonly errorType = ContainerErrorType.genericError; | ||
readonly errorType = ContainerErrorType.genericError; | ||
/** | ||
* Create a new GenericError | ||
* @param message - Error message | ||
* @param error - inner error object | ||
* @param props - Telemetry props to include when the error is logged | ||
*/ | ||
constructor( | ||
message: string, | ||
readonly error?: any, | ||
props?: ITelemetryProperties, | ||
) { | ||
// Don't try to log the inner error | ||
super(message, props, new Set(["error"])); | ||
} | ||
/** | ||
* Create a new GenericError | ||
* @param message - Error message | ||
* @param error - inner error object | ||
* @param props - Telemetry props to include when the error is logged | ||
*/ | ||
constructor(message: string, readonly error?: any, props?: ITelemetryProperties) { | ||
// Don't try to log the inner error | ||
super(message, props, new Set(["error"])); | ||
} | ||
} | ||
@@ -53,25 +49,24 @@ | ||
export class ThrottlingWarning extends LoggingError implements IThrottlingWarning, IFluidErrorBase { | ||
readonly errorType = ContainerErrorType.throttlingError; | ||
readonly errorType = ContainerErrorType.throttlingError; | ||
private constructor( | ||
message: string, | ||
readonly retryAfterSeconds: number, | ||
props?: ITelemetryProperties, | ||
) { | ||
super(message, props); | ||
} | ||
private constructor( | ||
message: string, | ||
readonly retryAfterSeconds: number, | ||
props?: ITelemetryProperties, | ||
) { | ||
super(message, props); | ||
} | ||
/** | ||
* Wrap the given error as a ThrottlingWarning | ||
* Only preserves the error message, and applies the given retry after to the new warning object | ||
*/ | ||
static wrap( | ||
error: unknown, | ||
retryAfterSeconds: number, | ||
logger: ITelemetryLogger, | ||
): IThrottlingWarning { | ||
const newErrorFn = | ||
(errMsg: string) => new ThrottlingWarning(errMsg, retryAfterSeconds); | ||
return wrapErrorAndLog(error, newErrorFn, logger); | ||
} | ||
/** | ||
* Wrap the given error as a ThrottlingWarning | ||
* Only preserves the error message, and applies the given retry after to the new warning object | ||
*/ | ||
static wrap( | ||
error: unknown, | ||
retryAfterSeconds: number, | ||
logger: ITelemetryLogger, | ||
): IThrottlingWarning { | ||
const newErrorFn = (errMsg: string) => new ThrottlingWarning(errMsg, retryAfterSeconds); | ||
return wrapErrorAndLog(error, newErrorFn, logger); | ||
} | ||
} | ||
@@ -81,9 +76,7 @@ | ||
export class UsageError extends LoggingError implements IUsageError, IFluidErrorBase { | ||
readonly errorType = ContainerErrorType.usageError; | ||
readonly errorType = ContainerErrorType.usageError; | ||
constructor( | ||
message: string, | ||
) { | ||
super(message, { usageError: true }); | ||
} | ||
constructor(message: string) { | ||
super(message, { usageError: true }); | ||
} | ||
} | ||
@@ -93,10 +86,7 @@ | ||
export class ClientSessionExpiredError extends LoggingError implements IFluidErrorBase { | ||
readonly errorType = ContainerErrorType.clientSessionExpiredError; | ||
readonly errorType = ContainerErrorType.clientSessionExpiredError; | ||
constructor( | ||
message: string, | ||
readonly expiryMs: number, | ||
) { | ||
super(message, { timeoutMs: expiryMs }); | ||
} | ||
constructor(message: string, readonly expiryMs: number) { | ||
super(message, { timeoutMs: expiryMs }); | ||
} | ||
} | ||
@@ -109,11 +99,8 @@ | ||
export class DataCorruptionError extends LoggingError implements IErrorBase, IFluidErrorBase { | ||
readonly errorType = ContainerErrorType.dataCorruptionError; | ||
readonly canRetry = false; | ||
readonly errorType = ContainerErrorType.dataCorruptionError; | ||
readonly canRetry = false; | ||
constructor( | ||
message: string, | ||
props: ITelemetryProperties, | ||
) { | ||
super(message, { ...props, dataProcessingError: 1 }); | ||
} | ||
constructor(message: string, props: ITelemetryProperties) { | ||
super(message, { ...props, dataProcessingError: 1 }); | ||
} | ||
} | ||
@@ -128,72 +115,80 @@ | ||
export class DataProcessingError extends LoggingError implements IErrorBase, IFluidErrorBase { | ||
readonly errorType = ContainerErrorType.dataProcessingError; | ||
readonly canRetry = false; | ||
readonly errorType = ContainerErrorType.dataProcessingError; | ||
readonly canRetry = false; | ||
private constructor(errorMessage: string) { | ||
super(errorMessage); | ||
} | ||
private constructor(errorMessage: string) { | ||
super(errorMessage); | ||
} | ||
/** Create a new DataProcessingError detected and raised with the FF code */ | ||
static create( | ||
errorMessage: string, | ||
dataProcessingCodepath: string, | ||
sequencedMessage?: ISequencedDocumentMessage, | ||
props: ITelemetryProperties = {}, | ||
) { | ||
const dataProcessingError = DataProcessingError.wrapIfUnrecognized( | ||
errorMessage, | ||
dataProcessingCodepath, | ||
sequencedMessage); | ||
dataProcessingError.addTelemetryProperties(props); | ||
/** Create a new DataProcessingError detected and raised with the FF code */ | ||
static create( | ||
errorMessage: string, | ||
dataProcessingCodepath: string, | ||
sequencedMessage?: ISequencedDocumentMessage, | ||
props: ITelemetryProperties = {}, | ||
) { | ||
const dataProcessingError = DataProcessingError.wrapIfUnrecognized( | ||
errorMessage, | ||
dataProcessingCodepath, | ||
sequencedMessage, | ||
); | ||
dataProcessingError.addTelemetryProperties(props); | ||
return dataProcessingError; | ||
} | ||
return dataProcessingError; | ||
} | ||
/** | ||
* Wrap the given error in a DataProcessingError, unless the error is already of a known type | ||
* with the exception of a normalized LoggingError, which will still be wrapped. | ||
* In either case, the error will have some relevant properties added for telemetry | ||
* We wrap conditionally since known error types represent well-understood failure modes, and ideally | ||
* one day we will move away from throwing these errors but rather we'll return them. | ||
* But an unrecognized error needs to be classified as DataProcessingError. | ||
* @param originalError - error to be converted | ||
* @param dataProcessingCodepath - which codepath failed while processing data | ||
* @param sequencedMessage - Sequenced message to include info about via telemetry props | ||
* @returns Either a new DataProcessingError, or (if wrapping is deemed unnecessary) the given error | ||
*/ | ||
static wrapIfUnrecognized( | ||
originalError: any, | ||
dataProcessingCodepath: string, | ||
sequencedMessage?: ISequencedDocumentMessage, | ||
): IFluidErrorBase { | ||
const props = { | ||
dataProcessingError: 1, | ||
dataProcessingCodepath, | ||
...(sequencedMessage === undefined ? undefined : extractSafePropertiesFromMessage(sequencedMessage)), | ||
}; | ||
/** | ||
* Wrap the given error in a DataProcessingError, unless the error is already of a known type | ||
* with the exception of a normalized LoggingError, which will still be wrapped. | ||
* In either case, the error will have some relevant properties added for telemetry | ||
* We wrap conditionally since known error types represent well-understood failure modes, and ideally | ||
* one day we will move away from throwing these errors but rather we'll return them. | ||
* But an unrecognized error needs to be classified as DataProcessingError. | ||
* @param originalError - error to be converted | ||
* @param dataProcessingCodepath - which codepath failed while processing data | ||
* @param sequencedMessage - Sequenced message to include info about via telemetry props | ||
* @returns Either a new DataProcessingError, or (if wrapping is deemed unnecessary) the given error | ||
*/ | ||
static wrapIfUnrecognized( | ||
originalError: any, | ||
dataProcessingCodepath: string, | ||
sequencedMessage?: ISequencedDocumentMessage, | ||
): IFluidErrorBase { | ||
const props = { | ||
dataProcessingError: 1, | ||
dataProcessingCodepath, | ||
...(sequencedMessage === undefined | ||
? undefined | ||
: extractSafePropertiesFromMessage(sequencedMessage)), | ||
}; | ||
const normalizedError = normalizeError(originalError, { props }); | ||
// Note that other errors may have the NORMALIZED_ERROR_TYPE errorType, | ||
// but if so they are still suitable to be wrapped as DataProcessingError. | ||
if (isExternalError(normalizedError) || normalizedError.errorType === NORMALIZED_ERROR_TYPE) { | ||
// Create a new DataProcessingError to wrap this external error | ||
const dataProcessingError = | ||
wrapError(normalizedError, (message: string) => new DataProcessingError(message)); | ||
const normalizedError = normalizeError(originalError, { props }); | ||
// Note that other errors may have the NORMALIZED_ERROR_TYPE errorType, | ||
// but if so they are still suitable to be wrapped as DataProcessingError. | ||
if ( | ||
isExternalError(normalizedError) || | ||
normalizedError.errorType === NORMALIZED_ERROR_TYPE | ||
) { | ||
// Create a new DataProcessingError to wrap this external error | ||
const dataProcessingError = wrapError( | ||
normalizedError, | ||
(message: string) => new DataProcessingError(message), | ||
); | ||
// Copy over the props above and any others added to this error since first being normalized | ||
dataProcessingError.addTelemetryProperties(normalizedError.getTelemetryProperties()); | ||
// Copy over the props above and any others added to this error since first being normalized | ||
dataProcessingError.addTelemetryProperties(normalizedError.getTelemetryProperties()); | ||
return dataProcessingError; | ||
} | ||
return normalizedError; | ||
} | ||
return dataProcessingError; | ||
} | ||
return normalizedError; | ||
} | ||
} | ||
export const extractSafePropertiesFromMessage = (message: ISequencedDocumentMessage) => ({ | ||
messageClientId: message.clientId, | ||
messageSequenceNumber: message.sequenceNumber, | ||
messageClientSequenceNumber: message.clientSequenceNumber, | ||
messageReferenceSequenceNumber: message.referenceSequenceNumber, | ||
messageMinimumSequenceNumber: message.minimumSequenceNumber, | ||
messageTimestamp: message.timestamp, | ||
messageClientId: message.clientId, | ||
messageSequenceNumber: message.sequenceNumber, | ||
messageClientSequenceNumber: message.clientSequenceNumber, | ||
messageReferenceSequenceNumber: message.referenceSequenceNumber, | ||
messageMinimumSequenceNumber: message.minimumSequenceNumber, | ||
messageTimestamp: message.timestamp, | ||
}); |
@@ -9,2 +9,2 @@ /*! | ||
export const pkgName = "@fluidframework/container-utils"; | ||
export const pkgVersion = "2.0.0-dev.2.3.0.115467"; | ||
export const pkgVersion = "2.0.0-dev.3.1.0.125672"; |
{ | ||
"extends": "./tsconfig.json", | ||
"compilerOptions": { | ||
"outDir": "./lib", | ||
"module": "esnext" | ||
}, | ||
} | ||
"extends": "./tsconfig.json", | ||
"compilerOptions": { | ||
"outDir": "./lib", | ||
"module": "esnext", | ||
}, | ||
} |
{ | ||
"extends": "@fluidframework/build-common/ts-common-config.json", | ||
"exclude": [ | ||
"src/test/**/*" | ||
], | ||
"compilerOptions": { | ||
"rootDir": "./src", | ||
"outDir": "./dist", | ||
"composite": true | ||
}, | ||
"include": [ | ||
"src/**/*" | ||
] | ||
} | ||
"extends": "@fluidframework/build-common/ts-common-config.json", | ||
"exclude": ["src/test/**/*"], | ||
"compilerOptions": { | ||
"rootDir": "./src", | ||
"outDir": "./dist", | ||
"composite": true, | ||
}, | ||
"include": ["src/**/*"], | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
2893
67994
737
+ Added@fluidframework/container-definitions@2.0.0-dev.3.1.0.125672(transitive)
+ Added@fluidframework/core-interfaces@2.0.0-dev.3.1.0.125672(transitive)
+ Added@fluidframework/driver-definitions@2.0.0-dev.3.1.0.125672(transitive)
+ Added@fluidframework/telemetry-utils@2.0.0-dev.3.1.0.125672(transitive)
- Removed@fluidframework/container-definitions@2.0.0-dev.2.3.0.115467(transitive)
- Removed@fluidframework/core-interfaces@2.0.0-dev.2.3.0.115467(transitive)
- Removed@fluidframework/driver-definitions@2.0.0-dev.2.3.0.115467(transitive)
- Removed@fluidframework/telemetry-utils@2.0.0-dev.2.3.0.115467(transitive)
Updated@fluidframework/container-definitions@>=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0
Updated@fluidframework/telemetry-utils@>=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0