Skip to content

Commit

Permalink
feat(smithy-client): implement SdkException class (#3261)
Browse files Browse the repository at this point in the history
* feat(smithy-client): add utils to inject unmodeled error members

* feat(smithy-client): rename SdkException to ServiceException

* docs(smithy-client): document SmithyException
  • Loading branch information
AllanZhengYP authored Jan 29, 2022
1 parent 669d802 commit 6a23634
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 0 deletions.
39 changes: 39 additions & 0 deletions packages/smithy-client/src/exceptions.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { decorateServiceException, ServiceException } from "./exceptions";

it("ServiceException extends from Error", () => {
expect(
new ServiceException({
name: "Error",
message: "",
$fault: "client",
$metadata: {},
})
).toBeInstanceOf(Error);
});

describe("decorateServiceException", () => {
const exception = new ServiceException({
name: "Error",
message: "Error",
$fault: "client",
$metadata: {},
});

it("should inject unmodeled members to the exception", () => {
const decorated = decorateServiceException(exception, { foo: "foo" });
expect((decorated as any).foo).toBe("foo");
});

it("should not inject unmodeled members to the undefined", () => {
const decorated = decorateServiceException(exception, { message: undefined });
expect(decorated.message).toBe("Error");
});

it("should replace Message with message", () => {
const decorated = decorateServiceException({
name: "Error",
Message: "message",
} as any);
expect(decorated.message).toBe("message");
});
});
51 changes: 51 additions & 0 deletions packages/smithy-client/src/exceptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { HttpResponse, MetadataBearer, ResponseMetadata, RetryableTrait, SmithyException } from "@aws-sdk/types";

export interface ServiceExceptionOptions extends SmithyException, MetadataBearer {
message?: string;
}

/**
* Base exception class for the exceptions from the server-side.
*/
export class ServiceException extends Error implements SmithyException, MetadataBearer {
readonly $fault: "client" | "server";

$response?: HttpResponse;
$retryable?: RetryableTrait;
$metadata: ResponseMetadata;

constructor(options: ServiceExceptionOptions) {
super(options.message);
Object.setPrototypeOf(this, ServiceException.prototype);
this.name = options.name;
this.$fault = options.$fault;
this.$metadata = options.$metadata;
}
}

/**
* This method inject unmodeled member to a deserialized SDK exception,
* and load the error message from different possible keys('message',
* 'Message').
*
* @internal
*/
export const decorateServiceException = <E extends ServiceException>(
exception: E,
additions: { [key: string]: any } = {}
): E => {
// apply additional properties to deserialized ServiceException object
Object.entries(additions)
.filter(([, v]) => v !== undefined)
.forEach(([k, v]) => {
// @ts-ignore assign unmodeled keys
exception[k] = v;
});
// load error message from possible locations
// @ts-expect-error message could exist in Message key.
const message = exception.message || exception.Message || "UnknownError";
exception.message = message;
// @ts-expect-error
delete exception.Message;
return exception;
};
1 change: 1 addition & 0 deletions packages/smithy-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from "./constants";
export * from "./date-utils";
export * from "./defaults-mode";
export * from "./emitWarningIfUnsupportedVersion";
export * from "./exceptions";
export * from "./extended-encode-uri-component";
export * from "./get-array-if-single-item";
export * from "./get-value-from-text-node";
Expand Down
4 changes: 4 additions & 0 deletions packages/types/src/shapes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface RetryableTrait {
/**
* Type that is implemented by all Smithy shapes marked with the
* error trait.
* @deprecated
*/
export interface SmithyException {
/**
Expand Down Expand Up @@ -53,4 +54,7 @@ export interface SmithyException {
readonly $response?: HttpResponse;
}

/**
* @deprecated
*/
export type SdkError = Error & Partial<SmithyException> & Partial<MetadataBearer>;

0 comments on commit 6a23634

Please sign in to comment.