Skip to content

Commit 1e623ac

Browse files
astuyvetlhunter
authored andcommitted
fix: Handle case where Lambda handler is using callbacks instead of promises (#3404)
1 parent 315e688 commit 1e623ac

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

packages/dd-trace/src/lambda/handler.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ exports.datadog = function datadog (lambdaHandler) {
8686
const context = extractContext(args)
8787

8888
checkTimeout(context)
89-
return lambdaHandler.apply(this, args).then((res) => { clearTimeout(__lambdaTimeout); return res })
89+
const result = lambdaHandler.apply(this, args)
90+
if (result && typeof result.then === 'function') {
91+
return result.then((res) => {
92+
clearTimeout(__lambdaTimeout)
93+
return res
94+
})
95+
}
96+
return result
9097
}
9198
}

packages/dd-trace/test/lambda/fixtures/handler.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ const handler = async (_event, _context) => {
2020
return response
2121
}
2222

23+
const callbackHandler = (_event, _context, callback) => {
24+
const response = sampleResponse
25+
26+
callback('', response)
27+
}
28+
2329
const timeoutHandler = async (...args) => {
2430
await _tracer.trace('self.sleepy', () => {
2531
return sleep(50)
@@ -63,5 +69,6 @@ module.exports = {
6369
handler,
6470
swappedArgsHandler,
6571
timeoutHandler,
66-
errorHandler
72+
errorHandler,
73+
callbackHandler
6774
}

packages/dd-trace/test/lambda/index.spec.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,43 @@ describe('lambda', () => {
9898
await checkTraces
9999
})
100100

101+
it('patches lambda function with callback correctly', async () => {
102+
// Set the desired handler to patch
103+
process.env.DD_LAMBDA_HANDLER = 'handler.callbackHandler'
104+
// Load the agent and re-register hook for patching.
105+
await loadAgent()
106+
107+
const _context = {
108+
getRemainingTimeInMillis: () => 150
109+
}
110+
const _event = {}
111+
112+
// Mock `datadog-lambda` handler resolve and import.
113+
const _handlerPath = path.resolve(__dirname, './fixtures/handler.js')
114+
const app = require(_handlerPath)
115+
datadog = require('./fixtures/datadog-lambda')
116+
let result
117+
const callback = (_error, res) => {
118+
result = res
119+
}
120+
// Run the function.
121+
datadog(app.callbackHandler)(_event, _context, callback)
122+
123+
expect(result).to.not.equal(undefined)
124+
const body = JSON.parse(result.body)
125+
expect(body.message).to.equal('hello!')
126+
127+
// Expect traces to be correct.
128+
const checkTraces = agent.use((_traces) => {
129+
const traces = _traces[0]
130+
expect(traces).lengthOf(1)
131+
traces.forEach((trace) => {
132+
expect(trace.error).to.equal(0)
133+
})
134+
})
135+
await checkTraces
136+
})
137+
101138
it('does wrap handler causing unhandled promise rejections', async () => {
102139
// Set the desired handler to patch
103140
process.env.DD_LAMBDA_HANDLER = 'handler.handler'

0 commit comments

Comments
 (0)