Skip to content

Commit dbcb961

Browse files
authored
New: [AEA-4355] - Updates error handler to support step function event formats (#181)
## Summary - Routine Change - ✨ New Feature ### Details - Updates error handler to support pulling meta date from step function events
1 parent 7b3c1cd commit dbcb961

File tree

2 files changed

+94
-63
lines changed

2 files changed

+94
-63
lines changed

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ function errorHandler({logger = console, level = "error"}: LoggerAndLevel) {
3434
onError: async (handler) => {
3535
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3636
const error: any = handler.error
37-
const requestId = handler.event.requestContext?.requestId ?? null
38-
const timeEpoch = handler.event.requestContext?.timeEpoch ?? null
37+
const requestId = handler.event.requestContext?.requestId ?? handler.event.headers?.["apigw-request-id"] ?? null
38+
const timeEpoch = handler.event.requestContext?.timeEpoch ?? Date.now()
3939

4040
// if there are a `statusCode` and an `error` field
4141
// this is a valid http error object

tests/index.test.ts

Lines changed: 92 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -55,81 +55,112 @@ const mockEvent = {
5555
stageVariables: {}
5656
}
5757

58-
test("Middleware logs all error details", async () => {
59-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
60-
type ErrorLogger = (error: any, message: string) => void
61-
const mockErrorLogger: jest.MockedFunction<ErrorLogger> = jest.fn()
62-
const mockLogger = {
63-
error: mockErrorLogger
64-
}
65-
66-
const handler = middy(() => {
67-
throw new Error("error running lambda")
58+
const mockStateMachineEvent = {
59+
body: {},
60+
headers: {
61+
"apigw-request-id": "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
62+
"nhsd-correlation-id": "test-request-id.test-correlation-id.rrt-5789322914740101037-b-aet2-20145-482635-2",
63+
"nhsd-nhslogin-user": "P9:9912003071",
64+
"nhsd-request-id": "test-request-id",
65+
"x-correlation-id": "test-correlation-id",
66+
"x-request-id": "test-request-id"
67+
},
68+
querystring: {},
69+
path: {}
70+
}
71+
72+
describe("Middy Error Handler", () => {
73+
beforeAll(() => {
74+
jest.useFakeTimers()
75+
jest.setSystemTime(new Date("2015-04-09T12:34:56.001Z"))
6876
})
6977

70-
handler.use(errorHandler({logger: mockLogger}))
78+
test("Middleware logs all error details", async () => {
79+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
80+
type ErrorLogger = (error: any, message: string) => void
81+
const mockErrorLogger: jest.MockedFunction<ErrorLogger> = jest.fn()
82+
const mockLogger = {
83+
error: mockErrorLogger
84+
}
7185

72-
await handler({}, {})
86+
const handler = middy(() => {
87+
throw new Error("error running lambda")
88+
})
7389

74-
expect(mockErrorLogger).toHaveBeenCalledTimes(1)
90+
handler.use(errorHandler({logger: mockLogger}))
7591

76-
const [errorObject, errorMessage] = mockErrorLogger.mock.calls[mockErrorLogger.mock.calls.length - 1]
77-
expect(errorMessage).toBe("Error: error running lambda")
78-
expect(errorObject.error.name).toBe("Error")
79-
expect(errorObject.error.message).toBe("error running lambda")
80-
expect(errorObject.error.stack).not.toBeNull()
81-
})
92+
await handler({}, {})
8293

83-
test("Middleware returns details as valid fhir from lambda event", async () => {
84-
const mockLogger = {
85-
error: jest.fn(() => {})
86-
}
94+
expect(mockErrorLogger).toHaveBeenCalledTimes(1)
8795

88-
const handler = middy(() => {
89-
throw new Error("error running lambda")
96+
const [errorObject, errorMessage] = mockErrorLogger.mock.calls[mockErrorLogger.mock.calls.length - 1]
97+
expect(errorMessage).toBe("Error: error running lambda")
98+
expect(errorObject.error.name).toBe("Error")
99+
expect(errorObject.error.message).toBe("error running lambda")
100+
expect(errorObject.error.stack).not.toBeNull()
90101
})
91102

92-
handler.use(errorHandler({logger: mockLogger}))
93-
94-
const response = await handler(mockEvent, {})
95-
expect(response.statusCode).toBe(500)
96-
expect(JSON.parse(response.body)).toMatchObject({
97-
id: "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
98-
meta: {
99-
lastUpdated: "2015-04-09T12:34:56.001Z"
103+
test.each([
104+
{
105+
event: mockEvent,
106+
description: "Middleware returns details as valid fhir from apigw event"
100107
},
101-
resourceType: "OperationOutcome",
102-
issue: [
103-
{
104-
severity: "fatal",
105-
code: "exception",
106-
details: {
107-
coding: [
108-
{
109-
code: "SERVER_ERROR",
110-
display: "500: The Server has encountered an error processing the request.",
111-
system: "https://fhir.nhs.uk/CodeSystem/http-error-codes"
112-
}
113-
]
108+
{
109+
event: mockStateMachineEvent,
110+
description: "Middleware returns details as valid fhir from step function event"
111+
}
112+
])("$description", async ({event}) => {
113+
const mockLogger = {
114+
error: jest.fn(() => {})
115+
}
116+
117+
const handler = middy(() => {
118+
throw new Error("error running lambda")
119+
})
120+
121+
handler.use(errorHandler({logger: mockLogger}))
122+
123+
const response = await handler(event, {})
124+
expect(response.statusCode).toBe(500)
125+
expect(JSON.parse(response.body)).toMatchObject({
126+
id: "c6af9ac6-7b61-11e6-9a41-93e8deadbeef",
127+
meta: {
128+
lastUpdated: "2015-04-09T12:34:56.001Z"
129+
},
130+
resourceType: "OperationOutcome",
131+
issue: [
132+
{
133+
severity: "fatal",
134+
code: "exception",
135+
details: {
136+
coding: [
137+
{
138+
code: "SERVER_ERROR",
139+
display: "500: The Server has encountered an error processing the request.",
140+
system: "https://fhir.nhs.uk/CodeSystem/http-error-codes"
141+
}
142+
]
143+
}
114144
}
115-
}
116-
]
145+
]
146+
})
117147
})
118-
})
119148

120-
test("Returns a response with the correct MIME type", async () => {
121-
const mockLogger = {
122-
error: jest.fn(() => {})
123-
}
124-
const handler = middy(() => {
125-
throw new Error("error running lambda")
126-
})
127-
handler.use(errorHandler({logger: mockLogger}))
149+
test("Returns a response with the correct MIME type", async () => {
150+
const mockLogger = {
151+
error: jest.fn(() => {})
152+
}
153+
const handler = middy(() => {
154+
throw new Error("error running lambda")
155+
})
156+
handler.use(errorHandler({logger: mockLogger}))
128157

129-
const response = await handler(mockEvent, {})
158+
const response = await handler(mockEvent, {})
130159

131-
expect(response.headers).toEqual({
132-
"Content-Type": "application/fhir+json",
133-
"Cache-Control": "no-cache"
160+
expect(response.headers).toEqual({
161+
"Content-Type": "application/fhir+json",
162+
"Cache-Control": "no-cache"
163+
})
134164
})
165+
135166
})

0 commit comments

Comments
 (0)