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

recordSpanException(error: Error | unknown): void

Basic Usage

import { RespanTelemetry } from '@respan/tracing';
const respanAi = new RespanTelemetry({
apiKey: process.env.RESPAN_API_KEY,
appName: 'my-app'
});
await respanAi.initialize();
await respanAi.withTask(
{ name: 'database_query' },
async () => {
const client = respanAi.getClient();
try {
return await db.query('SELECT * FROM users');
} catch (error) {
client.recordSpanException(error);
throw error;
}
}
);

With Status Update

await respanAi.withWorkflow(
{ name: 'payment_processing' },
async () => {
const client = respanAi.getClient();
try {
const payment = await processPayment();
client.updateCurrentSpan({ status: 'OK' });
return payment;
} catch (error) {
client.recordSpanException(error);
client.updateCurrentSpan({
status: 'ERROR',
attributes: {
'error.type': error.name,
'error.recoverable': false
}
});
throw error;
}
}
);

Multiple Exception Tracking

await respanAi.withTask(
{ name: 'multi_step_operation' },
async () => {
const client = respanAi.getClient();
const errors = [];
try {
await step1();
} catch (error) {
client.recordSpanException(error);
errors.push(error);
}
try {
await step2();
} catch (error) {
client.recordSpanException(error);
errors.push(error);
}
if (errors.length > 0) {
throw new Error(`${errors.length} steps failed`);
}
return 'success';
}
);

Retry Logic with Exception Tracking

await respanAi.withTask(
{ name: 'retry_operation' },
async () => {
const client = respanAi.getClient();
let lastError;
for (let attempt = 0; attempt < 3; attempt++) {
try {
client.addSpanEvent('retry_attempt', {
attempt: attempt + 1
});
return await unstableApiCall();
} catch (error) {
lastError = error;
client.recordSpanException(error);
client.addSpanEvent('retry_failed', {
attempt: attempt + 1,
error: error.message
});
if (attempt < 2) {
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
}
throw lastError;
}
);

Custom Error Context

await respanAi.withWorkflow(
{ name: 'data_sync' },
async () => {
const client = respanAi.getClient();
try {
await syncData();
} catch (error) {
// Add context before recording
client.updateCurrentSpan({
attributes: {
'sync.source': 'external_api',
'sync.destination': 'database',
'sync.records_attempted': 1000,
'error.during': 'data_sync'
}
});
client.recordSpanException(error);
throw error;
}
}
);

Graceful Degradation

await respanAi.withAgent(
{ name: 'ai_assistant' },
async () => {
const client = respanAi.getClient();
try {
// Try primary LLM provider
return await callOpenAI();
} catch (error) {
client.recordSpanException(error);
client.addSpanEvent('fallback_to_secondary', {
primary_provider: 'openai',
error: error.message
});
try {
// Fallback to secondary provider
return await callAnthropic();
} catch (fallbackError) {
client.recordSpanException(fallbackError);
client.updateCurrentSpan({ status: 'ERROR' });
throw new Error('All providers failed');
}
}
}
);

With User Notification

await respanAi.withWorkflow(
{ name: 'user_operation' },
async () => {
const client = respanAi.getClient();
try {
return await performOperation();
} catch (error) {
const traceId = client.getCurrentTraceId();
client.recordSpanException(error);
client.updateCurrentSpan({
respan_params: {
metadata: {
error_reported: true,
trace_id_shared: traceId
}
}
});
// Provide trace ID to user for support
throw new Error(
`Operation failed. Support reference: ${traceId}`
);
}
}
);

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