Skip to content

Commit b94ddc8

Browse files
author
Martin Pirkl
authored
Merge pull request #649 from enter-at/feat/conflict-error
feat(errors): add support for http 409 conflict
2 parents 7afb863 + e80d2cf commit b94ddc8

File tree

6 files changed

+40
-1
lines changed

6 files changed

+40
-1
lines changed

src/error/ConflictError.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { LambdaHandlerError } from "./LambdaHandlerError";
2+
3+
export class ConflictError extends LambdaHandlerError {
4+
public readonly name = "ConflictError";
5+
}

src/error/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export { RequestTimeoutError } from "./RequestTimeoutError";
88
export { UnauthorizedError } from "./UnauthorizedError";
99
export { ValidationError } from "./ValidationError";
1010
export { UnprocessableEntityError } from "./UnprocessableEntityError";
11+
export { ConflictError } from "./ConflictError";

src/handler/APIGatewayProxyHandler.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { ok, created, noContent } from "../response";
1414
import * as ContextFactory from "../../test/fixtures/ContextFactory";
1515
import * as APIGatewayProxyEventFactory from "../../test/fixtures/APIGatewayProxyEventFactory";
1616
import { UnprocessableEntityError } from "../error/UnprocessableEntityError";
17+
import { ConflictError } from "../error/ConflictError";
1718

1819
describe(APIGatewayProxyHandler.name, () => {
1920
let handler: APIGatewayProxyHandler;
@@ -133,4 +134,13 @@ describe(APIGatewayProxyHandler.name, () => {
133134
const result = await fn(event, context, () => undefined);
134135
expect(result).toMatchSnapshot();
135136
});
137+
138+
it("handles ConflictError response correctly", async () => {
139+
const fn = handler.wrapper(() => {
140+
throw new ConflictError("ConflictError message");
141+
}) as Handler<APIGatewayProxyEvent, APIGatewayProxyResult>;
142+
143+
const result = await fn(event, context, () => undefined);
144+
expect(result).toMatchSnapshot();
145+
});
136146
});

src/handler/APIGatewayProxyHandler.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ import {
77
RequestTimeoutError,
88
ValidationError,
99
UnauthorizedError,
10+
UnprocessableEntityError,
11+
ConflictError,
1012
} from "../error";
11-
import { UnprocessableEntityError } from "../error";
1213
import { ContentTypeHeader, CORSHeader, Header, Headers } from "../header";
1314
import {
1415
badRequest,
@@ -21,6 +22,7 @@ import {
2122
requestTimeout,
2223
unauthorized,
2324
unprocessableEntity,
25+
conflict,
2426
} from "../response";
2527
import { BaseHandler, BaseHandlerArguments } from "./BaseHandler";
2628
import { config } from "../index";
@@ -49,6 +51,9 @@ export class APIGatewayProxyHandler extends BaseHandler {
4951
if (err instanceof NotFoundError) {
5052
return notFound(err.details);
5153
}
54+
if (err instanceof ConflictError) {
55+
return conflict(err.details);
56+
}
5257
config.logger.error({
5358
name: err.name,
5459
message: err.message,

src/handler/__snapshots__/APIGatewayProxyHandler.spec.ts.snap

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@ Object {
1212
}
1313
`;
1414

15+
exports[`APIGatewayProxyHandler handles ConflictError response correctly 1`] = `
16+
Object {
17+
"body": "{\\"errors\\":[{\\"name\\":\\"ConflictError\\",\\"details\\":\\"ConflictError message\\"}]}",
18+
"headers": Object {
19+
"Access-Control-Allow-Credentials": true,
20+
"Access-Control-Allow-Origin": "*",
21+
"Content-Type": "application/json",
22+
},
23+
"statusCode": 409,
24+
}
25+
`;
26+
1527
exports[`APIGatewayProxyHandler handles ForbiddenError response correctly 1`] = `
1628
Object {
1729
"body": "{\\"errors\\":[{\\"name\\":\\"ForbiddenError\\",\\"details\\":\\"ForbiddenError message\\"}]}",

src/response.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
UnauthorizedError,
1111
UnprocessableEntityError,
1212
} from "./error";
13+
import { ConflictError } from "./error/ConflictError";
1314

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

54+
export function conflict(details: string | undefined): APIGatewayResponse {
55+
const error: ConflictError = new ConflictError(details);
56+
return buildResult<ConflictError>(error, constants.HTTP_STATUS_CONFLICT);
57+
}
58+
5359
export function ok<T>(result: T): APIGatewayResponse {
5460
return buildResult<T>(result, constants.HTTP_STATUS_OK);
5561
}

0 commit comments

Comments
 (0)