Skip to content

Commit b0316da

Browse files
authoredFeb 27, 2025··
fix(opentelemetry): add error message to span status (#1632)
1 parent 319a3cf commit b0316da

File tree

4 files changed

+39
-1
lines changed

4 files changed

+39
-1
lines changed
 

‎package-lock.json

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/interceptors-opentelemetry/src/instrumentation.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ async function wrapWithSpan<T>(
4444
return ret;
4545
} catch (err: any) {
4646
if (acceptableErrors === undefined || !acceptableErrors(err)) {
47-
span.setStatus({ code: otel.SpanStatusCode.ERROR });
47+
span.setStatus({ code: otel.SpanStatusCode.ERROR, message: err instanceof Error ? err.message : String(err) });
4848
span.recordException(err);
4949
} else {
5050
span.setStatus({ code: otel.SpanStatusCode.OK });

‎packages/test/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"@opentelemetry/core": "^1.19.0",
3131
"@opentelemetry/exporter-trace-otlp-grpc": "^0.46.0",
3232
"@opentelemetry/sdk-node": "^0.46.0",
33+
"@opentelemetry/sdk-trace-base": "^1.19.0",
3334
"@opentelemetry/semantic-conventions": "^1.19.0",
3435
"@temporalio/activity": "file:../activity",
3536
"@temporalio/client": "file:../client",

‎packages/test/src/test-otel.ts

+35
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import { SpanStatusCode } from '@opentelemetry/api';
88
import { ExportResultCode } from '@opentelemetry/core';
99
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
1010
import * as opentelemetry from '@opentelemetry/sdk-node';
11+
import { BasicTracerProvider, InMemorySpanExporter, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
1112
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
1213
import test from 'ava';
1314
import { v4 as uuid4 } from 'uuid';
1415
import { Connection, WorkflowClient } from '@temporalio/client';
1516
import { OpenTelemetryWorkflowClientInterceptor } from '@temporalio/interceptors-opentelemetry/lib/client';
17+
import { instrument } from '@temporalio/interceptors-opentelemetry/lib/instrumentation';
1618
import {
1719
makeWorkflowExporter,
1820
OpenTelemetryActivityInboundInterceptor,
@@ -413,4 +415,37 @@ if (RUN_INTEGRATION_TESTS) {
413415
// Importing the otel workflow modules above should patch globalThis
414416
t.falsy((globalThis as any).window);
415417
});
418+
419+
test('instrumentation: Error status includes message and records exception', async (t) => {
420+
const memoryExporter = new InMemorySpanExporter();
421+
const provider = new BasicTracerProvider();
422+
provider.addSpanProcessor(new SimpleSpanProcessor(memoryExporter));
423+
provider.register();
424+
const tracer = provider.getTracer('test-error-tracer');
425+
426+
const errorMessage = 'Test error message';
427+
428+
await t.throwsAsync(
429+
instrument({
430+
tracer,
431+
spanName: 'test-error-span',
432+
fn: async () => {
433+
throw new Error(errorMessage);
434+
},
435+
}),
436+
{ message: errorMessage }
437+
);
438+
439+
const spans = memoryExporter.getFinishedSpans();
440+
t.is(spans.length, 1);
441+
442+
const span = spans[0];
443+
444+
t.is(span.status.code, SpanStatusCode.ERROR);
445+
446+
t.is(span.status.message, errorMessage);
447+
448+
const exceptionEvents = span.events.filter((event) => event.name === 'exception');
449+
t.is(exceptionEvents.length, 1);
450+
});
416451
}

0 commit comments

Comments
 (0)
Please sign in to comment.