← Files TemporalARCHIVED FILE
skills/temporal-developer/references/typescript/error-handling.md
3.28 KB · Oct 3, 2026 · 06:08 UTC
# TypeScript SDK Error Handling
## Overview
The TypeScript SDK uses `ApplicationFailure` for application errors with support for non-retryable marking.
## Application Failures
```typescript
import { ApplicationFailure } from '@temporalio/workflow';
export async function myWorkflow(): Promise<void> {
throw ApplicationFailure.create({
message: 'Invalid input',
type: 'ValidationError',
nonRetryable: true,
});
}
```
## Activity Errors
```typescript
import { ApplicationFailure } from '@temporalio/activity';
export async function validateActivity(input: string): Promise<void> {
if (!isValid(input)) {
throw ApplicationFailure.create({
message: `Invalid input: ${input}`,
type: 'ValidationError',
nonRetryable: true,
});
}
}
```
## Handling Errors in Workflows
```typescript
import { proxyActivities, ApplicationFailure, log } from '@temporalio/workflow';
import type * as activities from './activities';
const { riskyActivity } = proxyActivities<typeof activities>({
startToCloseTimeout: '5 minutes',
});
export async function workflowWithErrorHandling(): Promise<string> {
try {
return await riskyActivity();
} catch (err) {
if (err instanceof ApplicationFailure) {
log.warn('Activity failed', { type: err.type, message: err.message });
}
throw err;
}
}
```
## Retry Configuration
```typescript
const { myActivity } = proxyActivities<typeof activities>({
startToCloseTimeout: '10 minutes',
retry: {
initialInterval: '1s',
backoffCoefficient: 2,
maximumInterval: '1m',
maximumAttempts: 5,
nonRetryableErrorTypes: ['ValidationError', 'PaymentError'],
},
});
```
**Note:** Only set retry options if you have a domain-specific reason to. The defaults are suitable for most use cases.
## Timeout Configuration
```typescript
const { myActivity } = proxyActivities<typeof activities>({
startToCloseTimeout: '5 minutes', // Single attempt
scheduleToCloseTimeout: '30 minutes', // Including retries
heartbeatTimeout: '30 seconds', // Between heartbeats
});
```
## Workflow Failure
Workflows can throw errors to indicate failure:
```typescript
import { ApplicationFailure } from '@temporalio/workflow';
export async function myWorkflow(): Promise<string> {
if (someCondition) {
throw ApplicationFailure.create({
message: 'Workflow failed due to invalid state',
type: 'InvalidStateError',
});
}
return 'success';
}
```
**Warning:** Do NOT use `nonRetryable: true` for workflow failures in most cases. Unlike activities, workflow retries are controlled by the caller, not retry policies. Use `nonRetryable` only for errors that are truly unrecoverable (e.g., invalid input that will never be valid).
## Idempotency
For idempotency patterns (using keys, making activities granular), see `core/patterns.md`.
## Best Practices
1. Use specific error types for different failure modes
2. Set `nonRetryable: true` for permanent failures in activities
3. Configure `nonRetryableErrorTypes` in retry policy
4. Log errors before re-raising
5. Use `ApplicationFailure` to catch activity failures in workflows
6. Use the appropriate `log` import for your context:
- In workflows: `import { log } from '@temporalio/workflow'` (replay-safe)
- In activities: `import { log } from '@temporalio/activity'`
SHA-256: b40078a343f8d251162c320cd98c1e66ff41af60e2c6560df3c86862b6da840a