recordSpanException()

Record an error or exception on the current span

Overview

recordSpanException() records an error or exception on the currently active span, making it visible in the Respan dashboard for debugging.

Signature

1recordSpanException(error: Error | unknown): void

Basic Usage

1import { RespanTelemetry } from '@respan/tracing';
2
3const respanAi = new RespanTelemetry({
4 apiKey: process.env.RESPAN_API_KEY,
5 appName: 'my-app'
6});
7
8await respanAi.initialize();
9
10await respanAi.withTask(
11 { name: 'database_query' },
12 async () => {
13 const client = respanAi.getClient();
14
15 try {
16 return await db.query('SELECT * FROM users');
17 } catch (error) {
18 client.recordSpanException(error);
19 throw error;
20 }
21 }
22);

With Status Update

1await respanAi.withWorkflow(
2 { name: 'payment_processing' },
3 async () => {
4 const client = respanAi.getClient();
5
6 try {
7 const payment = await processPayment();
8
9 client.updateCurrentSpan({ status: 'OK' });
10
11 return payment;
12 } catch (error) {
13 client.recordSpanException(error);
14 client.updateCurrentSpan({
15 status: 'ERROR',
16 attributes: {
17 'error.type': error.name,
18 'error.recoverable': false
19 }
20 });
21 throw error;
22 }
23 }
24);

Multiple Exception Tracking

1await respanAi.withTask(
2 { name: 'multi_step_operation' },
3 async () => {
4 const client = respanAi.getClient();
5 const errors = [];
6
7 try {
8 await step1();
9 } catch (error) {
10 client.recordSpanException(error);
11 errors.push(error);
12 }
13
14 try {
15 await step2();
16 } catch (error) {
17 client.recordSpanException(error);
18 errors.push(error);
19 }
20
21 if (errors.length > 0) {
22 throw new Error(`${errors.length} steps failed`);
23 }
24
25 return 'success';
26 }
27);

Retry Logic with Exception Tracking

1await respanAi.withTask(
2 { name: 'retry_operation' },
3 async () => {
4 const client = respanAi.getClient();
5 let lastError;
6
7 for (let attempt = 0; attempt < 3; attempt++) {
8 try {
9 client.addSpanEvent('retry_attempt', {
10 attempt: attempt + 1
11 });
12
13 return await unstableApiCall();
14 } catch (error) {
15 lastError = error;
16 client.recordSpanException(error);
17 client.addSpanEvent('retry_failed', {
18 attempt: attempt + 1,
19 error: error.message
20 });
21
22 if (attempt < 2) {
23 await new Promise(resolve => setTimeout(resolve, 1000));
24 }
25 }
26 }
27
28 throw lastError;
29 }
30);

Custom Error Context

1await respanAi.withWorkflow(
2 { name: 'data_sync' },
3 async () => {
4 const client = respanAi.getClient();
5
6 try {
7 await syncData();
8 } catch (error) {
9 // Add context before recording
10 client.updateCurrentSpan({
11 attributes: {
12 'sync.source': 'external_api',
13 'sync.destination': 'database',
14 'sync.records_attempted': 1000,
15 'error.during': 'data_sync'
16 }
17 });
18
19 client.recordSpanException(error);
20 throw error;
21 }
22 }
23);

Graceful Degradation

1await respanAi.withAgent(
2 { name: 'ai_assistant' },
3 async () => {
4 const client = respanAi.getClient();
5
6 try {
7 // Try primary LLM provider
8 return await callOpenAI();
9 } catch (error) {
10 client.recordSpanException(error);
11 client.addSpanEvent('fallback_to_secondary', {
12 primary_provider: 'openai',
13 error: error.message
14 });
15
16 try {
17 // Fallback to secondary provider
18 return await callAnthropic();
19 } catch (fallbackError) {
20 client.recordSpanException(fallbackError);
21 client.updateCurrentSpan({ status: 'ERROR' });
22 throw new Error('All providers failed');
23 }
24 }
25 }
26);

With User Notification

1await respanAi.withWorkflow(
2 { name: 'user_operation' },
3 async () => {
4 const client = respanAi.getClient();
5
6 try {
7 return await performOperation();
8 } catch (error) {
9 const traceId = client.getCurrentTraceId();
10
11 client.recordSpanException(error);
12 client.updateCurrentSpan({
13 respan_params: {
14 metadata: {
15 error_reported: true,
16 trace_id_shared: traceId
17 }
18 }
19 });
20
21 // Provide trace ID to user for support
22 throw new Error(
23 `Operation failed. Support reference: ${traceId}`
24 );
25 }
26 }
27);

Parameters

error
Error | unknownRequired

The error or exception object to record

Recorded Information

The exception recording captures:

  • Error message
  • Error type/name
  • Stack trace
  • Timestamp

Best Practices

  • Always record exceptions before re-throwing them
  • Combine with updateCurrentSpan() to set status to ERROR
  • Add context attributes before recording for better debugging
  • Record all errors, even if you handle them gracefully
  • Include trace IDs in user-facing error messages for support
  • Exception details are visible in the Respan dashboard
  • Only call within an active span