Skip to content

Commit b940c5c

Browse files
authored
Fix addAction crash when called without optional attributes (#218)
## Summary - `addAction(name)` crashes when the optional `attributes` argument is omitted because `span.setAttributes(undefined)` calls `Object.keys()` on `undefined` internally - Guard the `setAttributes` call so it only runs when `attributes` is defined - Add tests covering both cases (with and without attributes) ## Test plan - [ ] Existing unit tests pass - [ ] New test: `addAction('name')` without attributes does not throw and produces a span - [ ] New test: `addAction('name', { key: 'value' })` produces a span with the expected attribute
1 parent be67a19 commit b940c5c

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hyperdx/otel-web': patch
3+
---
4+
5+
Fix addAction crash when called without optional attributes argument

packages/otel-web/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,9 @@ export const Rum: RumOtelWebType = {
705705
const now = Date.now();
706706
const tracer = this.provider.getTracer('custom-action');
707707
const span = tracer.startSpan(name, { startTime: now });
708-
span.setAttributes(attributes);
708+
if (attributes) {
709+
span.setAttributes(attributes);
710+
}
709711
span.end(now);
710712
},
711713

packages/otel-web/test/SplunkOtelWeb.test.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ limitations under the License.
1515
*/
1616

1717
import { SpanAttributes } from '@opentelemetry/api';
18+
import { SpanProcessor } from '@opentelemetry/sdk-trace-base';
1819
import { expect } from 'chai';
19-
import Rum from '../src';
20+
import Rum, { INSTRUMENTATIONS_ALL_DISABLED } from '../src';
2021
import { updateSessionStatus } from '../src/session';
22+
import { SpanCapturer } from './utils';
2123

2224
describe('SplunkOtelWeb', () => {
2325
afterEach(() => {
@@ -146,4 +148,33 @@ describe('SplunkOtelWeb', () => {
146148
expect(Rum.inited).to.eq(false, 'Should be false after destroying.');
147149
});
148150
});
151+
152+
describe('addAction', () => {
153+
let capturer: SpanCapturer;
154+
155+
beforeEach(() => {
156+
Rum.init({
157+
app: 'app-name',
158+
beaconUrl: 'https://beacon',
159+
rumAuth: '<token>',
160+
instrumentations: INSTRUMENTATIONS_ALL_DISABLED,
161+
});
162+
163+
capturer = new SpanCapturer();
164+
Rum.provider?.addSpanProcessor(capturer as any as SpanProcessor);
165+
});
166+
167+
it('should not crash when called without attributes', () => {
168+
expect(() => Rum.addAction('test-action')).to.not.throw();
169+
expect(capturer.spans).to.have.lengthOf(1);
170+
expect(capturer.spans[0].name).to.eq('test-action');
171+
});
172+
173+
it('should set attributes when provided', () => {
174+
Rum.addAction('test-action', { key: 'value' });
175+
expect(capturer.spans).to.have.lengthOf(1);
176+
expect(capturer.spans[0].name).to.eq('test-action');
177+
expect(capturer.spans[0].attributes).to.deep.include({ key: 'value' });
178+
});
179+
});
149180
});

0 commit comments

Comments
 (0)