From 17691271968f357b30c1d5936f1bc95a7a46fae0 Mon Sep 17 00:00:00 2001 From: h6o <48004352+newbee1939@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:37:20 +0900 Subject: [PATCH 1/7] fix(span): enforce StatusCode precedence rules in setStatus per specification Signed-off-by: h6o <48004352+newbee1939@users.noreply.github.com> --- api/src/trace/span.ts | 11 +- .../opentelemetry-sdk-trace-base/src/Span.ts | 19 +- .../test/common/Span.test.ts | 245 +++++++++++++----- 3 files changed, 202 insertions(+), 73 deletions(-) diff --git a/api/src/trace/span.ts b/api/src/trace/span.ts index e62e53e19bc..ffa4143fafe 100644 --- a/api/src/trace/span.ts +++ b/api/src/trace/span.ts @@ -90,8 +90,15 @@ export interface Span { /** * Sets a status to the span. If used, this will override the default Span - * status. Default is {@link SpanStatusCode.UNSET}. SetStatus overrides the value - * of previous calls to SetStatus on the Span. + * status. Default is {@link SpanStatusCode.UNSET}. + * + * These values form a total order: Ok > Error > Unset. Setting + * {@link SpanStatusCode.OK} is final and any further attempts to change + * the status will be ignored. An attempt to set {@link SpanStatusCode.UNSET} + * is always ignored. + * + * `message` is only used with {@link SpanStatusCode.ERROR} and is ignored + * for other status codes. * * @param status the SpanStatus to set. */ diff --git a/packages/opentelemetry-sdk-trace-base/src/Span.ts b/packages/opentelemetry-sdk-trace-base/src/Span.ts index b9796aac302..5ace0340ac2 100644 --- a/packages/opentelemetry-sdk-trace-base/src/Span.ts +++ b/packages/opentelemetry-sdk-trace-base/src/Span.ts @@ -241,19 +241,26 @@ export class SpanImpl implements Span { setStatus(status: SpanStatus): this { if (this._isSpanEnded()) return this; - this.status = { ...status }; + if (status.code === SpanStatusCode.UNSET) return this; + if (this.status.code === SpanStatusCode.OK) return this; + + const newStatus: SpanStatus = { code: status.code }; // When using try-catch, the caught "error" is of type `any`. When then assigning `any` to `status.message`, // TypeScript will not error. While this can happen during use of any API, it is more common on Span#setStatus() // as it's likely used in a catch-block. Therefore, we validate if `status.message` is actually a string, null, or // undefined to avoid an incorrect type causing issues downstream. - if (this.status.message != null && typeof status.message !== 'string') { - diag.warn( - `Dropping invalid status.message of type '${typeof status.message}', expected 'string'` - ); - delete this.status.message; + if (status.code === SpanStatusCode.ERROR) { + if (typeof status.message === 'string') { + newStatus.message = status.message; + } else if (status.message != null) { + diag.warn( + `Dropping invalid status.message of type '${typeof status.message}', expected 'string'` + ); + } } + this.status = newStatus; return this; } diff --git a/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts index 9fbe7dd3a4e..b1640253995 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts @@ -940,51 +940,193 @@ describe('Span', () => { assert.strictEqual(span.events.length, 0); }); - it('should set an error status', () => { - const span = new SpanImpl({ - scope: tracer.instrumentationScope, - resource: tracer['_resource'], - context: ROOT_CONTEXT, - spanContext, - name, - kind: SpanKind.CLIENT, - spanLimits: tracer.getSpanLimits(), - spanProcessor: tracer['_spanProcessor'], + describe('setStatus', () => { + it('should set an error status', () => { + const span = new SpanImpl({ + scope: tracer.instrumentationScope, + resource: tracer['_resource'], + context: ROOT_CONTEXT, + spanContext, + name, + kind: SpanKind.CLIENT, + spanLimits: tracer.getSpanLimits(), + spanProcessor: tracer['_spanProcessor'], + }); + + span.setStatus({ + code: SpanStatusCode.ERROR, + message: 'This is an error', + }); + + assert.strictEqual(span.status.code, SpanStatusCode.ERROR); + assert.strictEqual(span.status.message, 'This is an error'); }); - span.setStatus({ - code: SpanStatusCode.ERROR, - message: 'This is an error', + + it('should drop non-string status message', function () { + const warnStub = sinon.spy(diag, 'warn'); + const span = new SpanImpl({ + scope: tracer.instrumentationScope, + resource: tracer['_resource'], + context: ROOT_CONTEXT, + spanContext, + name, + kind: SpanKind.CLIENT, + spanLimits: tracer.getSpanLimits(), + spanProcessor: tracer['_spanProcessor'], + }); + + span.setStatus({ + code: SpanStatusCode.ERROR, + message: new Error('this is not a string') as any, + }); + span.end(); + + assert.strictEqual(span.status.code, SpanStatusCode.ERROR); + assert.strictEqual(span.status.message, undefined); + sinon.assert.calledOnceWithExactly( + warnStub, + "Dropping invalid status.message of type 'object', expected 'string'" + ); }); - span.end(); - assert.strictEqual(span.status.code, SpanStatusCode.ERROR); - assert.strictEqual(span.status.message, 'This is an error'); - }); + it('should ignore attempts to set UNSET status', () => { + const span = new SpanImpl({ + scope: tracer.instrumentationScope, + resource: tracer['_resource'], + context: ROOT_CONTEXT, + spanContext, + name, + kind: SpanKind.CLIENT, + spanLimits: tracer.getSpanLimits(), + spanProcessor: tracer['_spanProcessor'], + }); - it('should drop non-string status message', function () { - const warnStub = sinon.spy(diag, 'warn'); - const span = new SpanImpl({ - scope: tracer.instrumentationScope, - resource: tracer['_resource'], - context: ROOT_CONTEXT, - spanContext, - name, - kind: SpanKind.CLIENT, - spanLimits: tracer.getSpanLimits(), - spanProcessor: tracer['_spanProcessor'], + span.setStatus({ code: SpanStatusCode.ERROR, message: 'error' }); + span.setStatus({ code: SpanStatusCode.UNSET }); + + assert.strictEqual(span.status.code, SpanStatusCode.ERROR); + assert.strictEqual(span.status.message, 'error'); }); - span.setStatus({ - code: SpanStatusCode.ERROR, - message: new Error('this is not a string') as any, + + it('should not allow overwriting OK status with ERROR', () => { + const span = new SpanImpl({ + scope: tracer.instrumentationScope, + resource: tracer['_resource'], + context: ROOT_CONTEXT, + spanContext, + name, + kind: SpanKind.CLIENT, + spanLimits: tracer.getSpanLimits(), + spanProcessor: tracer['_spanProcessor'], + }); + + span.setStatus({ code: SpanStatusCode.OK }); + span.setStatus({ code: SpanStatusCode.ERROR, message: 'error' }); + + assert.strictEqual(span.status.code, SpanStatusCode.OK); + assert.strictEqual(span.status.message, undefined); }); - span.end(); - assert.strictEqual(span.status.code, SpanStatusCode.ERROR); - assert.strictEqual(span.status.message, undefined); - sinon.assert.calledOnceWithExactly( - warnStub, - "Dropping invalid status.message of type 'object', expected 'string'" - ); + it('should not allow overwriting OK status with UNSET', () => { + const span = new SpanImpl({ + scope: tracer.instrumentationScope, + resource: tracer['_resource'], + context: ROOT_CONTEXT, + spanContext, + name, + kind: SpanKind.CLIENT, + spanLimits: tracer.getSpanLimits(), + spanProcessor: tracer['_spanProcessor'], + }); + + span.setStatus({ code: SpanStatusCode.OK }); + span.setStatus({ code: SpanStatusCode.UNSET }); + + assert.strictEqual(span.status.code, SpanStatusCode.OK); + }); + + it('should allow overwriting ERROR status with OK', () => { + const span = new SpanImpl({ + scope: tracer.instrumentationScope, + resource: tracer['_resource'], + context: ROOT_CONTEXT, + spanContext, + name, + kind: SpanKind.CLIENT, + spanLimits: tracer.getSpanLimits(), + spanProcessor: tracer['_spanProcessor'], + }); + + span.setStatus({ code: SpanStatusCode.ERROR, message: 'error' }); + span.setStatus({ code: SpanStatusCode.OK }); + + assert.strictEqual(span.status.code, SpanStatusCode.OK); + assert.strictEqual(span.status.message, undefined); + }); + + it('should ignore message for OK status', () => { + const span = new SpanImpl({ + scope: tracer.instrumentationScope, + resource: tracer['_resource'], + context: ROOT_CONTEXT, + spanContext, + name, + kind: SpanKind.CLIENT, + spanLimits: tracer.getSpanLimits(), + spanProcessor: tracer['_spanProcessor'], + }); + + span.setStatus({ code: SpanStatusCode.OK, message: 'should be ignored' }); + + assert.strictEqual(span.status.code, SpanStatusCode.OK); + assert.strictEqual(span.status.message, undefined); + }); + + it('should allow overwriting ERROR with another ERROR', () => { + const span = new SpanImpl({ + scope: tracer.instrumentationScope, + resource: tracer['_resource'], + context: ROOT_CONTEXT, + spanContext, + name, + kind: SpanKind.CLIENT, + spanLimits: tracer.getSpanLimits(), + spanProcessor: tracer['_spanProcessor'], + }); + + span.setStatus({ code: SpanStatusCode.ERROR, message: 'first' }); + span.setStatus({ code: SpanStatusCode.ERROR, message: 'second' }); + + assert.strictEqual(span.status.code, SpanStatusCode.ERROR); + assert.strictEqual(span.status.message, 'second'); + }); + + it('should not update status after span is ended', () => { + const span = new SpanImpl({ + scope: tracer.instrumentationScope, + resource: tracer['_resource'], + context: ROOT_CONTEXT, + spanContext, + name, + kind: SpanKind.CLIENT, + spanLimits: tracer.getSpanLimits(), + spanProcessor: tracer['_spanProcessor'], + }); + + span.setStatus({ + code: SpanStatusCode.ERROR, + message: 'This is an error', + }); + span.end(); + + span.setStatus({ + code: SpanStatusCode.OK, + message: 'OK', + }); + + assert.strictEqual(span.status.code, SpanStatusCode.ERROR); + assert.strictEqual(span.status.message, 'This is an error'); + }); }); it('should return ReadableSpan', () => { @@ -1179,33 +1321,6 @@ describe('Span', () => { assert.strictEqual(span.events.length, 2); }); - it('should return ReadableSpan with new status', () => { - const span = new SpanImpl({ - scope: tracer.instrumentationScope, - resource: tracer['_resource'], - context: ROOT_CONTEXT, - spanContext, - name, - kind: SpanKind.CLIENT, - spanLimits: tracer.getSpanLimits(), - spanProcessor: tracer['_spanProcessor'], - }); - span.setStatus({ - code: SpanStatusCode.ERROR, - message: 'This is an error', - }); - assert.strictEqual(span.status.code, SpanStatusCode.ERROR); - assert.strictEqual(span.status.message, 'This is an error'); - span.end(); - - // shouldn't update status - span.setStatus({ - code: SpanStatusCode.OK, - message: 'OK', - }); - assert.strictEqual(span.status.code, SpanStatusCode.ERROR); - }); - it('should only end a span once', () => { const span = new SpanImpl({ scope: tracer.instrumentationScope, From 349894c8dfa0b1d0c28b2e414af98dbf6ad90c51 Mon Sep 17 00:00:00 2001 From: h6o <48004352+newbee1939@users.noreply.github.com> Date: Tue, 3 Mar 2026 13:11:44 +0900 Subject: [PATCH 2/7] test(span): add unit tests for status handling in Span implementation Signed-off-by: h6o <48004352+newbee1939@users.noreply.github.com> --- .../test/common/Span.test.ts | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts index b1640253995..ae78d8d084e 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts @@ -962,6 +962,41 @@ describe('Span', () => { assert.strictEqual(span.status.message, 'This is an error'); }); + it('should set an OK status', () => { + const span = new SpanImpl({ + scope: tracer.instrumentationScope, + resource: tracer['_resource'], + context: ROOT_CONTEXT, + spanContext, + name, + kind: SpanKind.CLIENT, + spanLimits: tracer.getSpanLimits(), + spanProcessor: tracer['_spanProcessor'], + }); + + span.setStatus({ code: SpanStatusCode.OK }); + + assert.strictEqual(span.status.code, SpanStatusCode.OK); + assert.strictEqual(span.status.message, undefined); + }); + + it('should ignore attempts to set UNSET from initial state', () => { + const span = new SpanImpl({ + scope: tracer.instrumentationScope, + resource: tracer['_resource'], + context: ROOT_CONTEXT, + spanContext, + name, + kind: SpanKind.CLIENT, + spanLimits: tracer.getSpanLimits(), + spanProcessor: tracer['_spanProcessor'], + }); + + span.setStatus({ code: SpanStatusCode.UNSET }); + + assert.strictEqual(span.status.code, SpanStatusCode.UNSET); + }); + it('should drop non-string status message', function () { const warnStub = sinon.spy(diag, 'warn'); const span = new SpanImpl({ @@ -1082,6 +1117,27 @@ describe('Span', () => { assert.strictEqual(span.status.message, undefined); }); + it('should ignore message for UNSET status', () => { + const span = new SpanImpl({ + scope: tracer.instrumentationScope, + resource: tracer['_resource'], + context: ROOT_CONTEXT, + spanContext, + name, + kind: SpanKind.CLIENT, + spanLimits: tracer.getSpanLimits(), + spanProcessor: tracer['_spanProcessor'], + }); + + span.setStatus({ + code: SpanStatusCode.UNSET, + message: 'should be ignored', + }); + + assert.strictEqual(span.status.code, SpanStatusCode.UNSET); + assert.strictEqual(span.status.message, undefined); + }); + it('should allow overwriting ERROR with another ERROR', () => { const span = new SpanImpl({ scope: tracer.instrumentationScope, From d9b51c8b21d2deda670a51f5ce62b205687d3047 Mon Sep 17 00:00:00 2001 From: h6o <48004352+newbee1939@users.noreply.github.com> Date: Tue, 3 Mar 2026 13:23:17 +0900 Subject: [PATCH 3/7] chore(changelog): update CHANGELOG.md to include recent bug fix for StatusCode precedence rules in setStatus Signed-off-by: h6o <48004352+newbee1939@users.noreply.github.com> --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38bcb24c9fa..d2dd5946936 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2 ### :bug: Bug Fixes +* fix(sdk-trace): enforce StatusCode precedence rules in `setStatus` per specification @newbee1939 * fix(sdk-trace-web): propagate `optimised` flag in `getElementXPath` recursion [#6335](https://github.com/open-telemetry/opentelemetry-js/pull/6335) @akkupratap323 ### :books: Documentation From 83722c4d742256bb787940499ef35f9bb13e0703 Mon Sep 17 00:00:00 2001 From: h6o <48004352+newbee1939@users.noreply.github.com> Date: Tue, 3 Mar 2026 20:16:20 +0900 Subject: [PATCH 4/7] fix(shim-opentracing): split error tag status code tests to respect StatusCode precedence Signed-off-by: h6o <48004352+newbee1939@users.noreply.github.com> --- packages/opentelemetry-shim-opentracing/test/Shim.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/opentelemetry-shim-opentracing/test/Shim.test.ts b/packages/opentelemetry-shim-opentracing/test/Shim.test.ts index 7a36ebe8922..5e7a58f153c 100644 --- a/packages/opentelemetry-shim-opentracing/test/Shim.test.ts +++ b/packages/opentelemetry-shim-opentracing/test/Shim.test.ts @@ -327,7 +327,9 @@ describe('OpenTracing Shim', () => { span.setTag('error', false); assert.strictEqual(otSpan.status.code, SpanStatusCode.OK); + }); + it('maps string error tag to status code', () => { span.setTag('error', 'true'); assert.strictEqual(otSpan.status.code, SpanStatusCode.ERROR); @@ -350,7 +352,9 @@ describe('OpenTracing Shim', () => { span.addTags({ hello: 'stars', error: false }); assert.strictEqual(otSpan.status.code, SpanStatusCode.OK); + }); + it('maps string error tag to status code when adding multiple tags', () => { span.addTags({ hello: 'stars', error: 'true' }); assert.strictEqual(otSpan.status.code, SpanStatusCode.ERROR); From 9f3c1358074a44c7f34c5c3872d3fffd1c9d979b Mon Sep 17 00:00:00 2001 From: h6o <48004352+newbee1939@users.noreply.github.com> Date: Tue, 3 Mar 2026 21:30:44 +0900 Subject: [PATCH 5/7] docs(changelog): update sdk-trace-base StatusCode precedence docs Signed-off-by: h6o <48004352+newbee1939@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2dd5946936..ba1d4f25d17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2 ### :bug: Bug Fixes -* fix(sdk-trace): enforce StatusCode precedence rules in `setStatus` per specification @newbee1939 +* fix(sdk-trace-base): enforce StatusCode precedence rules in `setStatus` per specification [#6461](https://github.com/open-telemetry/opentelemetry-js/pull/6461) @newbee1939 * fix(sdk-trace-web): propagate `optimised` flag in `getElementXPath` recursion [#6335](https://github.com/open-telemetry/opentelemetry-js/pull/6335) @akkupratap323 ### :books: Documentation From 9a396f73c39bf0138c91b771542d0898270d1bb1 Mon Sep 17 00:00:00 2001 From: h6o <48004352+newbee1939@users.noreply.github.com> Date: Tue, 3 Mar 2026 22:04:38 +0900 Subject: [PATCH 6/7] docs(span): clarify setStatus method documentation and status precedence rules Signed-off-by: h6o <48004352+newbee1939@users.noreply.github.com> --- api/src/trace/span.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/api/src/trace/span.ts b/api/src/trace/span.ts index ffa4143fafe..df70161f807 100644 --- a/api/src/trace/span.ts +++ b/api/src/trace/span.ts @@ -89,18 +89,21 @@ export interface Span { addLinks(links: Link[]): this; /** - * Sets a status to the span. If used, this will override the default Span - * status. Default is {@link SpanStatusCode.UNSET}. + * Sets the status of the span. * - * These values form a total order: Ok > Error > Unset. Setting - * {@link SpanStatusCode.OK} is final and any further attempts to change - * the status will be ignored. An attempt to set {@link SpanStatusCode.UNSET} - * is always ignored. + * By default, a span has status {@link SpanStatusCode.UNSET}. + * Calling this method overrides that default. * - * `message` is only used with {@link SpanStatusCode.ERROR} and is ignored - * for other status codes. + * The status codes have a total order: `OK > ERROR > UNSET`. * - * @param status the SpanStatus to set. + * - Once {@link SpanStatusCode.OK} is set, any further attempts to change + * the status are ignored. + * - Any attempt to set {@link SpanStatusCode.UNSET} is always ignored. + * + * The `message` field is only used when {@link SpanStatusCode.ERROR} is set. + * For all other status codes, `message` is ignored. + * + * @param status The {@link SpanStatus} to set. */ setStatus(status: SpanStatus): this; From 18536bd45e26ae299fe7e9aed90230f7a820fa97 Mon Sep 17 00:00:00 2001 From: h6o <48004352+newbee1939@users.noreply.github.com> Date: Tue, 3 Mar 2026 22:26:42 +0900 Subject: [PATCH 7/7] test(span): update unit tests to reflect changes in status handling and precedence rules Signed-off-by: h6o <48004352+newbee1939@users.noreply.github.com> --- .../test/common/Span.test.ts | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts index ae78d8d084e..143c5adc09e 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/Span.test.ts @@ -1014,7 +1014,6 @@ describe('Span', () => { code: SpanStatusCode.ERROR, message: new Error('this is not a string') as any, }); - span.end(); assert.strictEqual(span.status.code, SpanStatusCode.ERROR); assert.strictEqual(span.status.message, undefined); @@ -1024,7 +1023,7 @@ describe('Span', () => { ); }); - it('should ignore attempts to set UNSET status', () => { + it('should ignore message for OK status', () => { const span = new SpanImpl({ scope: tracer.instrumentationScope, resource: tracer['_resource'], @@ -1036,14 +1035,13 @@ describe('Span', () => { spanProcessor: tracer['_spanProcessor'], }); - span.setStatus({ code: SpanStatusCode.ERROR, message: 'error' }); - span.setStatus({ code: SpanStatusCode.UNSET }); + span.setStatus({ code: SpanStatusCode.OK, message: 'should be ignored' }); - assert.strictEqual(span.status.code, SpanStatusCode.ERROR); - assert.strictEqual(span.status.message, 'error'); + assert.strictEqual(span.status.code, SpanStatusCode.OK); + assert.strictEqual(span.status.message, undefined); }); - it('should not allow overwriting OK status with ERROR', () => { + it('should ignore message for UNSET status', () => { const span = new SpanImpl({ scope: tracer.instrumentationScope, resource: tracer['_resource'], @@ -1055,14 +1053,16 @@ describe('Span', () => { spanProcessor: tracer['_spanProcessor'], }); - span.setStatus({ code: SpanStatusCode.OK }); - span.setStatus({ code: SpanStatusCode.ERROR, message: 'error' }); + span.setStatus({ + code: SpanStatusCode.UNSET, + message: 'should be ignored', + }); - assert.strictEqual(span.status.code, SpanStatusCode.OK); + assert.strictEqual(span.status.code, SpanStatusCode.UNSET); assert.strictEqual(span.status.message, undefined); }); - it('should not allow overwriting OK status with UNSET', () => { + it('should ignore attempts to set UNSET status', () => { const span = new SpanImpl({ scope: tracer.instrumentationScope, resource: tracer['_resource'], @@ -1074,13 +1074,14 @@ describe('Span', () => { spanProcessor: tracer['_spanProcessor'], }); - span.setStatus({ code: SpanStatusCode.OK }); + span.setStatus({ code: SpanStatusCode.ERROR, message: 'error' }); span.setStatus({ code: SpanStatusCode.UNSET }); - assert.strictEqual(span.status.code, SpanStatusCode.OK); + assert.strictEqual(span.status.code, SpanStatusCode.ERROR); + assert.strictEqual(span.status.message, 'error'); }); - it('should allow overwriting ERROR status with OK', () => { + it('should not allow overwriting OK status with ERROR', () => { const span = new SpanImpl({ scope: tracer.instrumentationScope, resource: tracer['_resource'], @@ -1092,14 +1093,14 @@ describe('Span', () => { spanProcessor: tracer['_spanProcessor'], }); - span.setStatus({ code: SpanStatusCode.ERROR, message: 'error' }); span.setStatus({ code: SpanStatusCode.OK }); + span.setStatus({ code: SpanStatusCode.ERROR, message: 'error' }); assert.strictEqual(span.status.code, SpanStatusCode.OK); assert.strictEqual(span.status.message, undefined); }); - it('should ignore message for OK status', () => { + it('should not allow overwriting OK status with UNSET', () => { const span = new SpanImpl({ scope: tracer.instrumentationScope, resource: tracer['_resource'], @@ -1111,13 +1112,13 @@ describe('Span', () => { spanProcessor: tracer['_spanProcessor'], }); - span.setStatus({ code: SpanStatusCode.OK, message: 'should be ignored' }); + span.setStatus({ code: SpanStatusCode.OK }); + span.setStatus({ code: SpanStatusCode.UNSET }); assert.strictEqual(span.status.code, SpanStatusCode.OK); - assert.strictEqual(span.status.message, undefined); }); - it('should ignore message for UNSET status', () => { + it('should allow overwriting ERROR status with OK', () => { const span = new SpanImpl({ scope: tracer.instrumentationScope, resource: tracer['_resource'], @@ -1129,12 +1130,10 @@ describe('Span', () => { spanProcessor: tracer['_spanProcessor'], }); - span.setStatus({ - code: SpanStatusCode.UNSET, - message: 'should be ignored', - }); + span.setStatus({ code: SpanStatusCode.ERROR, message: 'error' }); + span.setStatus({ code: SpanStatusCode.OK }); - assert.strictEqual(span.status.code, SpanStatusCode.UNSET); + assert.strictEqual(span.status.code, SpanStatusCode.OK); assert.strictEqual(span.status.message, undefined); });