Error Handling
LogTide provides a standardized exception structure that works across all programming languages, enabling consistent error tracking, grouping, and analysis.
Overview
When you log errors with LogTide SDKs, exceptions are automatically serialized into a
structured format stored in metadata.exception.
This enables:
Stack Trace Parsing
Automatic parsing of stack frames with file, function, and line information.
Error Grouping
Similar errors are grouped by fingerprint for easier triage.
Language Agnostic
Works with Node.js, Python, Go, PHP, Kotlin, C#, Rust, Ruby, and more.
Exception Chaining
Support for nested/caused-by exceptions in languages that support them.
Structured Exceptions
When you pass an error to the SDK's logging methods, it automatically serializes
the exception into the metadata.exception field:
// SDK automatically serializes the error
client.error('api', 'Request failed', new Error('Connection timeout'));
// Results in this log structure:
{
"time": "2025-01-30T12:00:00Z",
"service": "api",
"level": "error",
"message": "Request failed",
"metadata": {
"exception": {
"type": "Error",
"message": "Connection timeout",
"language": "nodejs",
"stacktrace": [
{ "file": "/app/src/api.ts", "function": "handleRequest", "line": 42 },
{ "file": "/app/src/server.ts", "function": "processRequest", "line": 128 }
],
"raw": "Error: Connection timeout\n at handleRequest (/app/src/api.ts:42:15)\n..."
}
}
} Backward Compatibility
If you send errors without using the SDK (e.g., via HTTP API with stack traces in the message), LogTide will attempt to parse them using language-specific regex patterns as a fallback.
StructuredException Interface
The structured exception format is defined as follows. All SDKs serialize errors into this format:
interface StructuredException {
/**
* Exception type/class name
* @example "TypeError", "NullPointerException", "ValueError"
*/
type: string;
/**
* Human-readable error message
*/
message: string;
/**
* Stack trace as an array of frames (top to bottom)
* First frame = where the error was thrown
*/
stacktrace?: StructuredStackFrame[];
/**
* Language hint for better fingerprinting
* @example "nodejs", "python", "java", "go", "php", "kotlin", "csharp", "rust", "ruby"
*/
language?: string;
/**
* Inner/cause exception (for wrapped exceptions)
* @example Java's "Caused by", JavaScript's error.cause
*/
cause?: StructuredException;
/**
* Additional exception metadata
* @example { code: "ECONNREFUSED", errno: -111 }
*/
metadata?: Record<string, unknown>;
/**
* Original raw stack trace as a string (fallback)
*/
raw?: string;
}
interface StructuredStackFrame {
/** File path or module name */
file?: string;
/** Function/method name */
function?: string;
/** Line number (1-based) */
line?: number;
/** Column number */
column?: number;
/** Additional frame metadata */
metadata?: Record<string, unknown>;
} SDK Examples
Node.js
import { LogTideClient } from '@logtide/sdk-node';
const client = new LogTideClient({
apiUrl: 'https://logs.example.com',
apiKey: 'lp_your_api_key',
// Or use a DSN string instead:
// dsn: 'https://[email protected]',
});
try {
await riskyOperation();
} catch (error) {
// Error is automatically serialized with stack trace
client.error('api', 'Operation failed', error);
}
// With error.cause (Node.js 16.9+)
try {
await fetchData();
} catch (error) {
throw new Error('Failed to fetch user data', { cause: error });
} Python
from logtide import LogTideClient
client = LogTideClient(
api_url="https://logs.example.com",
api_key="lp_your_api_key"
)
try:
risky_operation()
except Exception as e:
# Exception is automatically serialized with traceback
client.error("api", "Operation failed", exc=e)
# With exception chaining
try:
fetch_data()
except IOError as e:
raise ValueError("Failed to fetch user data") from e Go
import "github.com/logtide-dev/logtide-sdk-go"
client := logtide.NewClient(logtide.Config{
ApiURL: "https://logs.example.com",
ApiKey: "lp_your_api_key",
})
if err := riskyOperation(); err != nil {
// Error is serialized with stack trace (if using pkg/errors or similar)
client.Error("api", "Operation failed", logtide.WithError(err))
}
// With wrapped errors
if err := fetchData(); err != nil {
return fmt.Errorf("failed to fetch user data: %w", err)
} Manual HTTP (No SDK)
If you're not using an SDK, you can manually structure the exception in your metadata:
{
"logs": [{
"time": "2025-01-30T12:00:00Z",
"service": "api",
"level": "error",
"message": "Request failed",
"metadata": {
"exception": {
"type": "ConnectionError",
"message": "Failed to connect to database",
"language": "python",
"stacktrace": [
{ "file": "app/db.py", "function": "connect", "line": 45 },
{ "file": "app/api.py", "function": "handle_request", "line": 123 }
]
}
}
}]
} Fallback Behavior
When LogTide receives an error log, it processes exceptions in this order:
- Structured metadata.exception — Preferred. Parsed directly without regex.
- Text-based parsing — Falls back to regex parsing of the message field for known stack trace formats.
Text-based parsing supports these languages:
Recommendation
For best results, use an official SDK which handles serialization automatically. Text-based parsing may not work for custom log formatters or unsupported languages.
Best Practices
error.cause in JS, raise ... from in Python, %w in Go)
to preserve the original error context.
error for recoverable errors and
critical for unrecoverable/fatal errors.
Exception tracking is only enabled for these levels.