workflow 4.2.0-beta.71 → 4.2.0-beta.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +1 -1
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +1 -1
- package/dist/internal/errors.d.ts +1 -1
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +2 -2
- package/dist/observability.d.ts +20 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +20 -0
- package/docs/ai/defining-tools.mdx +6 -0
- package/docs/ai/index.mdx +3 -0
- package/docs/ai/message-queueing.mdx +2 -0
- package/docs/ai/resumable-streams.mdx +37 -4
- package/docs/ai/sleep-and-delays.mdx +2 -0
- package/docs/api-reference/meta.json +1 -1
- package/docs/api-reference/workflow/define-hook.mdx +2 -0
- package/docs/api-reference/workflow/get-writable.mdx +1 -0
- package/docs/api-reference/workflow-ai/durable-agent.mdx +2 -0
- package/docs/api-reference/workflow-ai/workflow-chat-transport.mdx +2 -0
- package/docs/api-reference/workflow-api/get-run.mdx +14 -0
- package/docs/api-reference/workflow-api/get-world.mdx +105 -0
- package/docs/api-reference/workflow-errors/entity-conflict-error.mdx +60 -0
- package/docs/api-reference/workflow-errors/hook-not-found-error.mdx +90 -0
- package/docs/api-reference/workflow-errors/meta.json +16 -0
- package/docs/api-reference/workflow-errors/run-expired-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/step-not-registered-error.mdx +56 -0
- package/docs/api-reference/workflow-errors/throttle-error.mdx +62 -0
- package/docs/api-reference/workflow-errors/too-early-error.mdx +62 -0
- package/docs/api-reference/workflow-errors/workflow-not-registered-error.mdx +57 -0
- package/docs/api-reference/workflow-errors/workflow-run-cancelled-error.mdx +56 -0
- package/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx +62 -0
- package/docs/api-reference/workflow-errors/workflow-run-not-found-error.mdx +56 -0
- package/docs/api-reference/workflow-errors/workflow-world-error.mdx +79 -0
- package/docs/changelog/index.mdx +15 -0
- package/docs/changelog/meta.json +5 -0
- package/docs/deploying/building-a-world.mdx +20 -0
- package/docs/deploying/world/postgres-world.mdx +7 -0
- package/docs/errors/hook-conflict.mdx +9 -3
- package/docs/errors/index.mdx +6 -0
- package/docs/errors/step-not-registered.mdx +66 -0
- package/docs/errors/webhook-invalid-respond-with-value.mdx +10 -0
- package/docs/errors/webhook-response-not-sent.mdx +8 -0
- package/docs/errors/workflow-not-registered.mdx +64 -0
- package/docs/foundations/errors-and-retries.mdx +29 -0
- package/docs/foundations/streaming.mdx +22 -0
- package/docs/getting-started/index.mdx +3 -3
- package/docs/getting-started/meta.json +15 -0
- package/docs/getting-started/nestjs.mdx +4 -8
- package/docs/testing/index.mdx +1 -1
- package/package.json +18 -12
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: StepNotRegisteredError
|
|
3
|
+
description: Thrown when a step function is not registered in the current deployment.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Catch StepNotRegisteredError when a step function cannot be found during execution.
|
|
6
|
+
related:
|
|
7
|
+
- /docs/errors/step-not-registered
|
|
8
|
+
- /docs/api-reference/workflow-errors/workflow-not-registered-error
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
`StepNotRegisteredError` is thrown when the runtime tries to execute a step function that is not registered in the current deployment. This is an infrastructure error — not a user code error. It typically indicates a build or bundling issue that caused the step to not be included in the deployment.
|
|
12
|
+
|
|
13
|
+
When this error occurs, the step fails (like a `FatalError`) and control is passed back to the workflow function, which can handle the failure gracefully.
|
|
14
|
+
|
|
15
|
+
```typescript lineNumbers
|
|
16
|
+
import { StepNotRegisteredError } from "workflow/errors"
|
|
17
|
+
declare const error: unknown; // @setup
|
|
18
|
+
|
|
19
|
+
if (StepNotRegisteredError.is(error)) { // [!code highlight]
|
|
20
|
+
console.error("Step not registered:", error.stepName);
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## API Signature
|
|
25
|
+
|
|
26
|
+
### Properties
|
|
27
|
+
|
|
28
|
+
<TSDoc
|
|
29
|
+
definition={`
|
|
30
|
+
interface StepNotRegisteredError {
|
|
31
|
+
/** The name of the step function that was not found. */
|
|
32
|
+
stepName: string;
|
|
33
|
+
/** The error message. */
|
|
34
|
+
message: string;
|
|
35
|
+
}
|
|
36
|
+
export default StepNotRegisteredError;`}
|
|
37
|
+
/>
|
|
38
|
+
|
|
39
|
+
### Static Methods
|
|
40
|
+
|
|
41
|
+
#### `StepNotRegisteredError.is(value)`
|
|
42
|
+
|
|
43
|
+
Type-safe check for `StepNotRegisteredError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
|
|
44
|
+
|
|
45
|
+
<Callout>
|
|
46
|
+
The `.is()` method works in server-side Node.js code (API routes, middleware, hooks). Inside `"use workflow"` functions, step errors arrive deserialized from the event log and won't be actual `StepNotRegisteredError` instances — use `error.message` matching instead. See the [troubleshooting page](/docs/errors/step-not-registered) for workflow-side error handling examples.
|
|
47
|
+
</Callout>
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { StepNotRegisteredError } from "workflow/errors"
|
|
51
|
+
declare const error: unknown; // @setup
|
|
52
|
+
|
|
53
|
+
if (StepNotRegisteredError.is(error)) {
|
|
54
|
+
// error is typed as StepNotRegisteredError
|
|
55
|
+
}
|
|
56
|
+
```
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: ThrottleError
|
|
3
|
+
description: Thrown when a request is rate-limited by the workflow backend.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Catch ThrottleError when a workflow storage operation is rate-limited (HTTP 429).
|
|
6
|
+
related:
|
|
7
|
+
- /docs/api-reference/workflow-errors/workflow-world-error
|
|
8
|
+
- /docs/api-reference/workflow-errors/too-early-error
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
`ThrottleError` is thrown when a request to the workflow backend is rate-limited. It corresponds to HTTP 429 Too Many Requests semantics.
|
|
12
|
+
|
|
13
|
+
The `retryAfter` property contains the number of seconds to wait before retrying.
|
|
14
|
+
|
|
15
|
+
<Callout>
|
|
16
|
+
The Workflow runtime handles this error automatically by backing off and retrying. You will only encounter it when interacting with world storage APIs directly.
|
|
17
|
+
</Callout>
|
|
18
|
+
|
|
19
|
+
```typescript lineNumbers
|
|
20
|
+
import { ThrottleError } from "workflow/errors"
|
|
21
|
+
declare const world: { events: { create(...args: any[]): Promise<any> } }; // @setup
|
|
22
|
+
declare const runId: string; // @setup
|
|
23
|
+
declare const event: any; // @setup
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
await world.events.create(runId, event);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
if (ThrottleError.is(error)) { // [!code highlight]
|
|
29
|
+
console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API Signature
|
|
35
|
+
|
|
36
|
+
### Properties
|
|
37
|
+
|
|
38
|
+
<TSDoc
|
|
39
|
+
definition={`
|
|
40
|
+
interface ThrottleError {
|
|
41
|
+
/** The number of seconds to wait before retrying. Present when the server sends a Retry-After header. */
|
|
42
|
+
retryAfter?: number;
|
|
43
|
+
/** The error message. */
|
|
44
|
+
message: string;
|
|
45
|
+
}
|
|
46
|
+
export default ThrottleError;`}
|
|
47
|
+
/>
|
|
48
|
+
|
|
49
|
+
### Static Methods
|
|
50
|
+
|
|
51
|
+
#### `ThrottleError.is(value)`
|
|
52
|
+
|
|
53
|
+
Type-safe check for `ThrottleError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { ThrottleError } from "workflow/errors"
|
|
57
|
+
declare const error: unknown; // @setup
|
|
58
|
+
|
|
59
|
+
if (ThrottleError.is(error)) {
|
|
60
|
+
// error is typed as ThrottleError
|
|
61
|
+
}
|
|
62
|
+
```
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: TooEarlyError
|
|
3
|
+
description: Thrown when a request is made before the system is ready to process it.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Catch TooEarlyError when a world operation is attempted before the system is ready.
|
|
6
|
+
related:
|
|
7
|
+
- /docs/api-reference/workflow-errors/workflow-world-error
|
|
8
|
+
- /docs/api-reference/workflow-errors/throttle-error
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
`TooEarlyError` is thrown by world implementations when a request is made before the system is ready to process it. It corresponds to HTTP 425 Too Early semantics.
|
|
12
|
+
|
|
13
|
+
The `retryAfter` property contains the number of seconds to wait before retrying.
|
|
14
|
+
|
|
15
|
+
<Callout>
|
|
16
|
+
The Workflow runtime handles this error automatically by retrying after the specified delay. You will only encounter it when interacting with world storage APIs directly.
|
|
17
|
+
</Callout>
|
|
18
|
+
|
|
19
|
+
```typescript lineNumbers
|
|
20
|
+
import { TooEarlyError } from "workflow/errors"
|
|
21
|
+
declare const world: { events: { create(...args: any[]): Promise<any> } }; // @setup
|
|
22
|
+
declare const runId: string; // @setup
|
|
23
|
+
declare const event: any; // @setup
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
await world.events.create(runId, event);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
if (TooEarlyError.is(error)) { // [!code highlight]
|
|
29
|
+
console.log(`Retry after ${error.retryAfter} seconds`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API Signature
|
|
35
|
+
|
|
36
|
+
### Properties
|
|
37
|
+
|
|
38
|
+
<TSDoc
|
|
39
|
+
definition={`
|
|
40
|
+
interface TooEarlyError {
|
|
41
|
+
/** Delay in seconds before the operation can be retried. Present when the server sends a Retry-After header. */
|
|
42
|
+
retryAfter?: number;
|
|
43
|
+
/** The error message. */
|
|
44
|
+
message: string;
|
|
45
|
+
}
|
|
46
|
+
export default TooEarlyError;`}
|
|
47
|
+
/>
|
|
48
|
+
|
|
49
|
+
### Static Methods
|
|
50
|
+
|
|
51
|
+
#### `TooEarlyError.is(value)`
|
|
52
|
+
|
|
53
|
+
Type-safe check for `TooEarlyError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { TooEarlyError } from "workflow/errors"
|
|
57
|
+
declare const error: unknown; // @setup
|
|
58
|
+
|
|
59
|
+
if (TooEarlyError.is(error)) {
|
|
60
|
+
// error is typed as TooEarlyError
|
|
61
|
+
}
|
|
62
|
+
```
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: WorkflowNotRegisteredError
|
|
3
|
+
description: Thrown when a workflow function is not registered in the current deployment.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Catch WorkflowNotRegisteredError when a workflow function cannot be found during execution.
|
|
6
|
+
related:
|
|
7
|
+
- /docs/errors/workflow-not-registered
|
|
8
|
+
- /docs/api-reference/workflow-errors/step-not-registered-error
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
`WorkflowNotRegisteredError` is thrown when the runtime tries to execute a workflow function that is not registered in the current deployment. This is an infrastructure error — not a user code error. It typically means a run was started against a deployment that does not have this workflow (e.g., the workflow was renamed or moved), or there was a build/bundling issue.
|
|
12
|
+
|
|
13
|
+
When this error occurs, the run fails with a `RUNTIME_ERROR` error code.
|
|
14
|
+
|
|
15
|
+
```typescript lineNumbers
|
|
16
|
+
import { WorkflowNotRegisteredError } from "workflow/errors"
|
|
17
|
+
declare const error: unknown; // @setup
|
|
18
|
+
|
|
19
|
+
if (WorkflowNotRegisteredError.is(error)) { // [!code highlight]
|
|
20
|
+
console.error("Workflow not registered:", error.workflowName);
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## API Signature
|
|
25
|
+
|
|
26
|
+
### Properties
|
|
27
|
+
|
|
28
|
+
<TSDoc
|
|
29
|
+
definition={`
|
|
30
|
+
interface WorkflowNotRegisteredError {
|
|
31
|
+
/** The name of the workflow function that was not found. */
|
|
32
|
+
workflowName: string;
|
|
33
|
+
/** The error message. */
|
|
34
|
+
message: string;
|
|
35
|
+
}
|
|
36
|
+
export default WorkflowNotRegisteredError;`}
|
|
37
|
+
/>
|
|
38
|
+
|
|
39
|
+
### Static Methods
|
|
40
|
+
|
|
41
|
+
#### `WorkflowNotRegisteredError.is(value)`
|
|
42
|
+
|
|
43
|
+
Type-safe check for `WorkflowNotRegisteredError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
|
|
44
|
+
|
|
45
|
+
<Callout>
|
|
46
|
+
The `.is()` method works in server-side Node.js code (API routes, middleware). When checking the error from `run.returnValue`, use `WorkflowRunFailedError.is()` and inspect `error.cause` — the underlying error is deserialized from the event log.
|
|
47
|
+
</Callout>
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { WorkflowNotRegisteredError } from "workflow/errors"
|
|
51
|
+
declare const error: unknown; // @setup
|
|
52
|
+
|
|
53
|
+
if (WorkflowNotRegisteredError.is(error)) {
|
|
54
|
+
// error is typed as WorkflowNotRegisteredError
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: WorkflowRunCancelledError
|
|
3
|
+
description: Thrown when awaiting the return value of a cancelled workflow run.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Catch WorkflowRunCancelledError when awaiting run.returnValue on a run that was cancelled.
|
|
6
|
+
related:
|
|
7
|
+
- /docs/api-reference/workflow-errors/workflow-run-failed-error
|
|
8
|
+
- /docs/api-reference/workflow-errors/workflow-run-not-found-error
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
`WorkflowRunCancelledError` is thrown when awaiting `run.returnValue` on a workflow run that was explicitly cancelled via `run.cancel()`. Cancelled runs do not produce a return value.
|
|
12
|
+
|
|
13
|
+
You can check for cancellation before awaiting by inspecting `run.status`.
|
|
14
|
+
|
|
15
|
+
```typescript lineNumbers
|
|
16
|
+
import { WorkflowRunCancelledError } from "workflow/errors"
|
|
17
|
+
declare const run: { status: Promise<string>; returnValue: Promise<any> }; // @setup
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const result = await run.returnValue;
|
|
21
|
+
} catch (error) {
|
|
22
|
+
if (WorkflowRunCancelledError.is(error)) { // [!code highlight]
|
|
23
|
+
console.log(`Run ${error.runId} was cancelled`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## API Signature
|
|
29
|
+
|
|
30
|
+
### Properties
|
|
31
|
+
|
|
32
|
+
<TSDoc
|
|
33
|
+
definition={`
|
|
34
|
+
interface WorkflowRunCancelledError {
|
|
35
|
+
/** The ID of the cancelled run. */
|
|
36
|
+
runId: string;
|
|
37
|
+
/** The error message. */
|
|
38
|
+
message: string;
|
|
39
|
+
}
|
|
40
|
+
export default WorkflowRunCancelledError;`}
|
|
41
|
+
/>
|
|
42
|
+
|
|
43
|
+
### Static Methods
|
|
44
|
+
|
|
45
|
+
#### `WorkflowRunCancelledError.is(value)`
|
|
46
|
+
|
|
47
|
+
Type-safe check for `WorkflowRunCancelledError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { WorkflowRunCancelledError } from "workflow/errors"
|
|
51
|
+
declare const error: unknown; // @setup
|
|
52
|
+
|
|
53
|
+
if (WorkflowRunCancelledError.is(error)) {
|
|
54
|
+
// error is typed as WorkflowRunCancelledError
|
|
55
|
+
}
|
|
56
|
+
```
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: WorkflowRunFailedError
|
|
3
|
+
description: Thrown when awaiting the return value of a failed workflow run.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Catch WorkflowRunFailedError when awaiting run.returnValue on a run that encountered a fatal error.
|
|
6
|
+
related:
|
|
7
|
+
- /docs/api-reference/workflow/fatal-error
|
|
8
|
+
- /docs/api-reference/workflow-errors/workflow-run-cancelled-error
|
|
9
|
+
- /docs/api-reference/workflow-errors/workflow-run-not-found-error
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
`WorkflowRunFailedError` is thrown when awaiting `run.returnValue` on a workflow run whose status is `'failed'`. This indicates that the workflow encountered a fatal error during execution and cannot produce a return value.
|
|
13
|
+
|
|
14
|
+
The `cause` property contains the underlying error with its message, stack trace, and optional error code.
|
|
15
|
+
|
|
16
|
+
```typescript lineNumbers
|
|
17
|
+
import { WorkflowRunFailedError } from "workflow/errors"
|
|
18
|
+
declare const run: { status: Promise<string>; returnValue: Promise<any> }; // @setup
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const result = await run.returnValue;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (WorkflowRunFailedError.is(error)) { // [!code highlight]
|
|
24
|
+
console.error(`Run ${error.runId} failed:`, error.cause.message);
|
|
25
|
+
if (error.cause.code) {
|
|
26
|
+
console.error("Error code:", error.cause.code);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## API Signature
|
|
33
|
+
|
|
34
|
+
### Properties
|
|
35
|
+
|
|
36
|
+
<TSDoc
|
|
37
|
+
definition={`
|
|
38
|
+
interface WorkflowRunFailedError {
|
|
39
|
+
/** The ID of the failed run. */
|
|
40
|
+
runId: string;
|
|
41
|
+
/** The underlying error that caused the failure. */
|
|
42
|
+
cause: Error & { code?: string };
|
|
43
|
+
/** The error message. */
|
|
44
|
+
message: string;
|
|
45
|
+
}
|
|
46
|
+
export default WorkflowRunFailedError;`}
|
|
47
|
+
/>
|
|
48
|
+
|
|
49
|
+
### Static Methods
|
|
50
|
+
|
|
51
|
+
#### `WorkflowRunFailedError.is(value)`
|
|
52
|
+
|
|
53
|
+
Type-safe check for `WorkflowRunFailedError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { WorkflowRunFailedError } from "workflow/errors"
|
|
57
|
+
declare const error: unknown; // @setup
|
|
58
|
+
|
|
59
|
+
if (WorkflowRunFailedError.is(error)) {
|
|
60
|
+
// error is typed as WorkflowRunFailedError
|
|
61
|
+
}
|
|
62
|
+
```
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: WorkflowRunNotFoundError
|
|
3
|
+
description: Thrown when operating on a workflow run that does not exist.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Catch WorkflowRunNotFoundError when performing operations on a non-existent workflow run.
|
|
6
|
+
related:
|
|
7
|
+
- /docs/api-reference/workflow-errors/workflow-run-failed-error
|
|
8
|
+
- /docs/api-reference/workflow-errors/workflow-run-cancelled-error
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
`WorkflowRunNotFoundError` is thrown when performing operations on a workflow run that does not exist. This includes calling methods like `run.status`, `run.cancel()`, or awaiting `run.returnValue` on a run whose ID does not match any known workflow run.
|
|
12
|
+
|
|
13
|
+
Note that `getRun(id)` itself is synchronous and will not throw — the error is raised when subsequent operations on the run object discover the run is missing.
|
|
14
|
+
|
|
15
|
+
```typescript lineNumbers
|
|
16
|
+
import { WorkflowRunNotFoundError } from "workflow/errors"
|
|
17
|
+
declare const run: { status: Promise<string>; returnValue: Promise<any> }; // @setup
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const status = await run.status;
|
|
21
|
+
} catch (error) {
|
|
22
|
+
if (WorkflowRunNotFoundError.is(error)) { // [!code highlight]
|
|
23
|
+
console.error(`Run ${error.runId} does not exist`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## API Signature
|
|
29
|
+
|
|
30
|
+
### Properties
|
|
31
|
+
|
|
32
|
+
<TSDoc
|
|
33
|
+
definition={`
|
|
34
|
+
interface WorkflowRunNotFoundError {
|
|
35
|
+
/** The ID of the run that was not found. */
|
|
36
|
+
runId: string;
|
|
37
|
+
/** The error message. */
|
|
38
|
+
message: string;
|
|
39
|
+
}
|
|
40
|
+
export default WorkflowRunNotFoundError;`}
|
|
41
|
+
/>
|
|
42
|
+
|
|
43
|
+
### Static Methods
|
|
44
|
+
|
|
45
|
+
#### `WorkflowRunNotFoundError.is(value)`
|
|
46
|
+
|
|
47
|
+
Type-safe check for `WorkflowRunNotFoundError` instances. Preferred over `instanceof` because it works across module boundaries and VM contexts.
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { WorkflowRunNotFoundError } from "workflow/errors"
|
|
51
|
+
declare const error: unknown; // @setup
|
|
52
|
+
|
|
53
|
+
if (WorkflowRunNotFoundError.is(error)) {
|
|
54
|
+
// error is typed as WorkflowRunNotFoundError
|
|
55
|
+
}
|
|
56
|
+
```
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: WorkflowWorldError
|
|
3
|
+
description: Base error for failures from workflow storage backends.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Catch WorkflowWorldError to handle any error originating from a workflow world (storage backend).
|
|
6
|
+
related:
|
|
7
|
+
- /docs/api-reference/workflow-errors/entity-conflict-error
|
|
8
|
+
- /docs/api-reference/workflow-errors/run-expired-error
|
|
9
|
+
- /docs/api-reference/workflow-errors/too-early-error
|
|
10
|
+
- /docs/api-reference/workflow-errors/throttle-error
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
`WorkflowWorldError` is the base error class for failures originating from a workflow world (storage backend). World implementations (local, Postgres, Vercel) throw subclasses of this error when storage operations fail.
|
|
14
|
+
|
|
15
|
+
You can use `instanceof WorkflowWorldError` to catch any world-related error regardless of the specific type. Note that the static `.is()` method only matches errors constructed directly as `WorkflowWorldError` — use the subclass-specific `.is()` methods (e.g. `EntityConflictError.is()`) to match specific error types.
|
|
16
|
+
|
|
17
|
+
<Callout>
|
|
18
|
+
Most world errors are handled automatically by the Workflow runtime. You will typically only encounter these errors when interacting with world storage APIs directly or when there are infrastructure-level issues.
|
|
19
|
+
</Callout>
|
|
20
|
+
|
|
21
|
+
```typescript lineNumbers
|
|
22
|
+
import { WorkflowWorldError } from "workflow/errors"
|
|
23
|
+
declare const world: { events: { create(...args: any[]): Promise<any> } }; // @setup
|
|
24
|
+
declare const runId: string; // @setup
|
|
25
|
+
declare const event: any; // @setup
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
await world.events.create(runId, event);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
if (error instanceof WorkflowWorldError) { // [!code highlight]
|
|
31
|
+
console.error("Storage backend error:", error.message);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## API Signature
|
|
37
|
+
|
|
38
|
+
### Properties
|
|
39
|
+
|
|
40
|
+
<TSDoc
|
|
41
|
+
definition={`
|
|
42
|
+
interface WorkflowWorldError {
|
|
43
|
+
/** HTTP status code from the world backend, if available. */
|
|
44
|
+
status?: number;
|
|
45
|
+
/** Machine-readable error code, if available. */
|
|
46
|
+
code?: string;
|
|
47
|
+
/** The URL that was requested, if available. */
|
|
48
|
+
url?: string;
|
|
49
|
+
/** Retry-After value in seconds, present on 429 and 425 responses. */
|
|
50
|
+
retryAfter?: number;
|
|
51
|
+
/** The error message. */
|
|
52
|
+
message: string;
|
|
53
|
+
}
|
|
54
|
+
export default WorkflowWorldError;`}
|
|
55
|
+
/>
|
|
56
|
+
|
|
57
|
+
### Static Methods
|
|
58
|
+
|
|
59
|
+
#### `WorkflowWorldError.is(value)`
|
|
60
|
+
|
|
61
|
+
Type-safe check that matches only errors constructed directly as `WorkflowWorldError`. Does not match subclasses like `EntityConflictError` — use `instanceof` to catch all world errors, or the subclass-specific `.is()` methods.
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { WorkflowWorldError } from "workflow/errors"
|
|
65
|
+
declare const error: unknown; // @setup
|
|
66
|
+
|
|
67
|
+
if (WorkflowWorldError.is(error)) {
|
|
68
|
+
// error is typed as WorkflowWorldError (not subclasses)
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Subclasses
|
|
73
|
+
|
|
74
|
+
The following error types extend `WorkflowWorldError`:
|
|
75
|
+
|
|
76
|
+
- [`EntityConflictError`](/docs/api-reference/workflow-errors/entity-conflict-error) — operation conflicts with entity state
|
|
77
|
+
- [`RunExpiredError`](/docs/api-reference/workflow-errors/run-expired-error) — run has expired
|
|
78
|
+
- [`TooEarlyError`](/docs/api-reference/workflow-errors/too-early-error) — request made before system is ready
|
|
79
|
+
- [`ThrottleError`](/docs/api-reference/workflow-errors/throttle-error) — request was rate-limited
|
|
@@ -180,11 +180,31 @@ interface Streamer {
|
|
|
180
180
|
): Promise<ReadableStream<Uint8Array>>;
|
|
181
181
|
|
|
182
182
|
listStreamsByRunId(runId: string): Promise<string[]>;
|
|
183
|
+
|
|
184
|
+
/** Paginated snapshot of stream chunks. */
|
|
185
|
+
getStreamChunks(
|
|
186
|
+
name: string,
|
|
187
|
+
runId: string,
|
|
188
|
+
options?: { limit?: number; cursor?: string }
|
|
189
|
+
): Promise<{
|
|
190
|
+
data: { index: number; data: Uint8Array }[];
|
|
191
|
+
cursor: string | null;
|
|
192
|
+
hasMore: boolean;
|
|
193
|
+
done: boolean;
|
|
194
|
+
}>;
|
|
195
|
+
|
|
196
|
+
/** Lightweight metadata: tail index and completion flag. */
|
|
197
|
+
getStreamInfo(
|
|
198
|
+
name: string,
|
|
199
|
+
runId: string
|
|
200
|
+
): Promise<{ tailIndex: number; done: boolean }>;
|
|
183
201
|
}
|
|
184
202
|
```
|
|
185
203
|
|
|
186
204
|
Streams are identified by a combination of `runId` and `name`. Each workflow run can have multiple named streams.
|
|
187
205
|
|
|
206
|
+
`getStreamChunks` returns a paginated snapshot of currently available chunks (unlike `readFromStream` which returns a live `ReadableStream` that waits for new chunks). `getStreamInfo` returns the tail index (last chunk index, 0-based, or `-1` when empty) and whether the stream is complete — useful for resolving negative `startIndex` values into absolute positions.
|
|
207
|
+
|
|
188
208
|
## Reference Implementations
|
|
189
209
|
|
|
190
210
|
Study these implementations for guidance:
|
|
@@ -160,6 +160,12 @@ Prefix for graphile-worker queue job names. Useful when sharing a database betwe
|
|
|
160
160
|
|
|
161
161
|
Number of concurrent workers polling for jobs. Default: `10`
|
|
162
162
|
|
|
163
|
+
### `WORKFLOW_POSTGRES_MAX_POOL_SIZE`
|
|
164
|
+
|
|
165
|
+
Maximum size of the internal `pg.Pool` used when `createWorld()` constructs the pool. Default: `10`
|
|
166
|
+
|
|
167
|
+
For higher worker concurrency, Graphile Worker recommends setting `maxPoolSize` to `10` or `queueConcurrency + 2`, whichever is larger.
|
|
168
|
+
|
|
163
169
|
### Programmatic configuration
|
|
164
170
|
|
|
165
171
|
{/* @skip-typecheck: incomplete code sample */}
|
|
@@ -170,6 +176,7 @@ const world = createWorld({
|
|
|
170
176
|
connectionString: "postgres://user:password@host:5432/database",
|
|
171
177
|
jobPrefix: "myapp_",
|
|
172
178
|
queueConcurrency: 20,
|
|
179
|
+
maxPoolSize: 20, // overrides WORKFLOW_POSTGRES_MAX_POOL_SIZE
|
|
173
180
|
});
|
|
174
181
|
```
|
|
175
182
|
|
|
@@ -46,6 +46,8 @@ export async function processPayment() {
|
|
|
46
46
|
**Solution:** Use unique tokens that include the run ID or other unique identifiers.
|
|
47
47
|
|
|
48
48
|
```typescript lineNumbers
|
|
49
|
+
import { createHook } from "workflow";
|
|
50
|
+
|
|
49
51
|
export async function processPayment(orderId: string) {
|
|
50
52
|
"use workflow";
|
|
51
53
|
|
|
@@ -60,6 +62,8 @@ export async function processPayment(orderId: string) {
|
|
|
60
62
|
The safest approach is to let the Workflow runtime generate a unique token automatically:
|
|
61
63
|
|
|
62
64
|
```typescript lineNumbers
|
|
65
|
+
import { createHook } from "workflow";
|
|
66
|
+
|
|
63
67
|
export async function processPayment() {
|
|
64
68
|
"use workflow";
|
|
65
69
|
|
|
@@ -71,10 +75,11 @@ export async function processPayment() {
|
|
|
71
75
|
|
|
72
76
|
## Handling Hook Conflicts in Your Workflow
|
|
73
77
|
|
|
74
|
-
When a hook conflict occurs, awaiting the hook will throw a `
|
|
78
|
+
When a hook conflict occurs, awaiting the hook will throw a `HookConflictError`. You can catch this error to handle the conflict gracefully:
|
|
75
79
|
|
|
76
80
|
```typescript lineNumbers
|
|
77
|
-
import {
|
|
81
|
+
import { createHook } from "workflow";
|
|
82
|
+
import { HookConflictError } from "@workflow/errors";
|
|
78
83
|
|
|
79
84
|
export async function processPayment(orderId: string) {
|
|
80
85
|
"use workflow";
|
|
@@ -85,8 +90,9 @@ export async function processPayment(orderId: string) {
|
|
|
85
90
|
const payment = await hook; // [!code highlight]
|
|
86
91
|
return { success: true, payment };
|
|
87
92
|
} catch (error) {
|
|
88
|
-
if (
|
|
93
|
+
if (HookConflictError.is(error)) { // [!code highlight]
|
|
89
94
|
// Another workflow is already processing this order
|
|
95
|
+
console.log(`Conflicting token: ${error.token}`);
|
|
90
96
|
return { success: false, reason: "duplicate-processing" };
|
|
91
97
|
}
|
|
92
98
|
throw error; // Re-throw other errors
|
package/docs/errors/index.mdx
CHANGED
|
@@ -37,6 +37,12 @@ Fix common mistakes when creating and executing workflows in the **Workflow DevK
|
|
|
37
37
|
<Card href="/docs/errors/corrupted-event-log" title="corrupted-event-log">
|
|
38
38
|
Learn how to handle corrupted or invalid event logs.
|
|
39
39
|
</Card>
|
|
40
|
+
<Card href="/docs/errors/step-not-registered" title="step-not-registered">
|
|
41
|
+
Resolve step not registered errors caused by deployment mismatches.
|
|
42
|
+
</Card>
|
|
43
|
+
<Card href="/docs/errors/workflow-not-registered" title="workflow-not-registered">
|
|
44
|
+
Resolve workflow not registered errors caused by deployment mismatches.
|
|
45
|
+
</Card>
|
|
40
46
|
</Cards>
|
|
41
47
|
|
|
42
48
|
## Learn More
|