Skip to content

Commit

Permalink
feat(errors): add support for http 409 conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Pirkl committed Oct 21, 2021
1 parent 7afb863 commit e80d2cf
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/error/ConflictError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { LambdaHandlerError } from "./LambdaHandlerError";

export class ConflictError extends LambdaHandlerError {
public readonly name = "ConflictError";
}
1 change: 1 addition & 0 deletions src/error/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export { RequestTimeoutError } from "./RequestTimeoutError";
export { UnauthorizedError } from "./UnauthorizedError";
export { ValidationError } from "./ValidationError";
export { UnprocessableEntityError } from "./UnprocessableEntityError";
export { ConflictError } from "./ConflictError";
10 changes: 10 additions & 0 deletions src/handler/APIGatewayProxyHandler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ok, created, noContent } from "../response";
import * as ContextFactory from "../../test/fixtures/ContextFactory";
import * as APIGatewayProxyEventFactory from "../../test/fixtures/APIGatewayProxyEventFactory";
import { UnprocessableEntityError } from "../error/UnprocessableEntityError";
import { ConflictError } from "../error/ConflictError";

describe(APIGatewayProxyHandler.name, () => {
let handler: APIGatewayProxyHandler;
Expand Down Expand Up @@ -133,4 +134,13 @@ describe(APIGatewayProxyHandler.name, () => {
const result = await fn(event, context, () => undefined);
expect(result).toMatchSnapshot();
});

it("handles ConflictError response correctly", async () => {
const fn = handler.wrapper(() => {
throw new ConflictError("ConflictError message");
}) as Handler<APIGatewayProxyEvent, APIGatewayProxyResult>;

const result = await fn(event, context, () => undefined);
expect(result).toMatchSnapshot();
});
});
7 changes: 6 additions & 1 deletion src/handler/APIGatewayProxyHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {
RequestTimeoutError,
ValidationError,
UnauthorizedError,
UnprocessableEntityError,
ConflictError,
} from "../error";
import { UnprocessableEntityError } from "../error";
import { ContentTypeHeader, CORSHeader, Header, Headers } from "../header";
import {
badRequest,
Expand All @@ -21,6 +22,7 @@ import {
requestTimeout,
unauthorized,
unprocessableEntity,
conflict,
} from "../response";
import { BaseHandler, BaseHandlerArguments } from "./BaseHandler";
import { config } from "../index";
Expand Down Expand Up @@ -49,6 +51,9 @@ export class APIGatewayProxyHandler extends BaseHandler {
if (err instanceof NotFoundError) {
return notFound(err.details);
}
if (err instanceof ConflictError) {
return conflict(err.details);
}
config.logger.error({
name: err.name,
message: err.message,
Expand Down
12 changes: 12 additions & 0 deletions src/handler/__snapshots__/APIGatewayProxyHandler.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ Object {
}
`;

exports[`APIGatewayProxyHandler handles ConflictError response correctly 1`] = `
Object {
"body": "{\\"errors\\":[{\\"name\\":\\"ConflictError\\",\\"details\\":\\"ConflictError message\\"}]}",
"headers": Object {
"Access-Control-Allow-Credentials": true,
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
},
"statusCode": 409,
}
`;

exports[`APIGatewayProxyHandler handles ForbiddenError response correctly 1`] = `
Object {
"body": "{\\"errors\\":[{\\"name\\":\\"ForbiddenError\\",\\"details\\":\\"ForbiddenError message\\"}]}",
Expand Down
6 changes: 6 additions & 0 deletions src/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
UnauthorizedError,
UnprocessableEntityError,
} from "./error";
import { ConflictError } from "./error/ConflictError";

export interface APIGatewayResponse extends Omit<APIGatewayProxyResult, "body"> {
body: unknown | undefined;
Expand Down Expand Up @@ -50,6 +51,11 @@ export function unprocessableEntity(details: string | undefined): APIGatewayResp
return buildResult<UnprocessableEntityError>(error, constants.HTTP_STATUS_UNPROCESSABLE_ENTITY);
}

export function conflict(details: string | undefined): APIGatewayResponse {
const error: ConflictError = new ConflictError(details);
return buildResult<ConflictError>(error, constants.HTTP_STATUS_CONFLICT);
}

export function ok<T>(result: T): APIGatewayResponse {
return buildResult<T>(result, constants.HTTP_STATUS_OK);
}
Expand Down

0 comments on commit e80d2cf

Please sign in to comment.