Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2b06b00

Browse files
committedApr 23, 2025·
Add unit tests for XRayError
1 parent 2ea9a34 commit 2b06b00

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed
 

‎test/unit/XRayErrorTest.js

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/**
2+
* Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*/
4+
5+
'use strict';
6+
7+
require('should');
8+
const { formatted } = require('lambda-runtime/XRayError.js');
9+
10+
describe('XRayFormattedCause', () => {
11+
it('should handle a basic error with stack trace', () => {
12+
const error = new Error('Something went wrong');
13+
error.name = 'CustomError';
14+
error.stack = `CustomError: Something went wrong
15+
at someFunction (/var/task/handler.js:10:15)`;
16+
17+
const result = JSON.parse(formatted(error));
18+
result.should.have.property('working_directory').which.is.a.String();
19+
result.should.have.property('exceptions').with.length(1);
20+
result.exceptions[0].should.have.property('type', 'CustomError');
21+
result.exceptions[0].should.have.property(
22+
'message',
23+
'Something went wrong',
24+
);
25+
result.exceptions[0].stack.should.deepEqual([
26+
{
27+
path: '/var/task/handler.js',
28+
line: 10,
29+
label: 'someFunction',
30+
},
31+
]);
32+
result.paths.should.deepEqual(['/var/task/handler.js']);
33+
});
34+
35+
it('should handle an error without stack trace', () => {
36+
const error = new Error('No stack here');
37+
error.name = 'NoStackError';
38+
error.stack = null;
39+
40+
const result = JSON.parse(formatted(error));
41+
result.exceptions[0].should.have.property('stack').with.length(0);
42+
result.paths.should.eql([]);
43+
});
44+
45+
it('should handle multiple stack frames', () => {
46+
const error = new Error('Complex error');
47+
error.name = 'ComplexError';
48+
error.stack = `ComplexError: Complex error
49+
at firstFunction (/var/task/one.js:1:100)
50+
at secondFunction (/var/task/two.js:2:200)
51+
at /var/task/three.js:3:300`;
52+
53+
const result = JSON.parse(formatted(error));
54+
result.exceptions[0].stack.should.deepEqual([
55+
{ path: '/var/task/one.js', line: 1, label: 'firstFunction' },
56+
{ path: '/var/task/two.js', line: 2, label: 'secondFunction' },
57+
{ path: '/var/task/three.js', line: 3, label: 'anonymous' },
58+
]);
59+
result.paths.should.eql([
60+
'/var/task/one.js',
61+
'/var/task/two.js',
62+
'/var/task/three.js',
63+
]);
64+
});
65+
66+
it('should encode invalid characters in name and message', () => {
67+
const error = new Error('\x7Fmessage');
68+
error.name = 'Name\x7F';
69+
70+
error.stack = `Name\x7F: \x7Fmessage
71+
at anon (/var/task/bad.js:99:1)`;
72+
73+
const result = JSON.parse(formatted(error));
74+
result.exceptions[0].type.should.equal('Name%7F');
75+
result.exceptions[0].message.should.equal('%7Fmessage');
76+
});
77+
78+
it('should return empty string on circular reference', () => {
79+
class CircularError extends Error {
80+
constructor() {
81+
super('circular');
82+
this.name = 'CircularError';
83+
this.circular = this;
84+
}
85+
86+
toString() {
87+
return 'CircularError: circular';
88+
}
89+
}
90+
91+
const error = new CircularError();
92+
error.stack = `CircularError: circular
93+
at circularFunction (/var/task/circle.js:1:1)`;
94+
95+
// Manually inject the circular object into a field that gets stringified
96+
const originalStack = error.stack;
97+
error.stack = {
98+
toString: () => {
99+
return originalStack;
100+
},
101+
};
102+
error.stack.circular = error.stack;
103+
104+
const result = formatted(error);
105+
result.should.equal('');
106+
});
107+
});

0 commit comments

Comments
 (0)
Please sign in to comment.