@@ -12,6 +12,60 @@ export type Failure<E extends ErrorObject = ErrorObject> = {
1212 error : E
1313}
1414
15+ /**
16+ * Result type for prompt functions that can be aborted.
17+ * Provides rich semantics to distinguish between successful completion and user abort.
18+ *
19+ * ## When to use `PromptResult<T>` vs `ErrorOr<T>`
20+ *
21+ * Use `PromptResult<T>` when:
22+ * - The operation can be cancelled by the user (via AbortSignal)
23+ * - An abort is an expected outcome, not an error
24+ * - You need to distinguish between errors (which might trigger fallbacks) and
25+ * user-initiated aborts (which should propagate immediately)
26+ *
27+ * Use `ErrorOr<T>` when:
28+ * - The operation can fail with an error that should be handled
29+ * - There's no concept of user-initiated abort
30+ * - You want to return error details rather than throw
31+ *
32+ * ## Abort handling patterns
33+ *
34+ * 1. **Check and return early** - For graceful handling where abort means "stop, no error":
35+ * ```ts
36+ * const result = await promptAiSdk({ ... })
37+ * if (result.aborted) return // or return null, false, etc.
38+ * doSomething(result.value)
39+ * ```
40+ *
41+ * 2. **Unwrap and throw** - For propagating aborts as exceptions:
42+ * ```ts
43+ * const value = unwrapPromptResult(await promptAiSdk({ ... }))
44+ * // Throws if aborted, callers should use isAbortError() in catch blocks
45+ * ```
46+ *
47+ * 3. **Rethrow in catch blocks** - Prevent swallowing abort errors:
48+ * ```ts
49+ * try {
50+ * await someOperation()
51+ * } catch (error) {
52+ * if (isAbortError(error)) throw error // Don't swallow aborts
53+ * // Handle other errors
54+ * }
55+ * ```
56+ */
57+ export type PromptResult < T > = PromptSuccess < T > | PromptAborted
58+
59+ export type PromptSuccess < T > = {
60+ aborted : false
61+ value : T
62+ }
63+
64+ export type PromptAborted = {
65+ aborted : true
66+ reason ?: string
67+ }
68+
1569export type ErrorObject = {
1670 name : string
1771 message : string
@@ -50,6 +104,72 @@ export function failure(error: unknown): Failure<ErrorObject> {
50104 }
51105}
52106
107+ /**
108+ * Create a successful prompt result.
109+ */
110+ export function promptSuccess < T > ( value : T ) : PromptSuccess < T > {
111+ return {
112+ aborted : false ,
113+ value,
114+ }
115+ }
116+
117+ /**
118+ * Create an aborted prompt result.
119+ */
120+ export function promptAborted ( reason ?: string ) : PromptAborted {
121+ return {
122+ aborted : true ,
123+ ...( reason !== undefined && { reason } ) ,
124+ }
125+ }
126+
127+ /**
128+ * Standard error message for aborted requests.
129+ * Use this constant when throwing abort errors to ensure consistency.
130+ */
131+ export const ABORT_ERROR_MESSAGE = 'Request aborted'
132+
133+ /**
134+ * Check if an error is an abort error.
135+ * Use this helper to detect abort errors in catch blocks.
136+ *
137+ * Detects both:
138+ * - Errors with message 'Request aborted' (thrown by our code via ABORT_ERROR_MESSAGE)
139+ * - Native AbortError (thrown by fetch/AI SDK when AbortSignal is triggered)
140+ */
141+ export function isAbortError ( error : unknown ) : boolean {
142+ if ( ! ( error instanceof Error ) ) {
143+ return false
144+ }
145+ // Check for our custom abort error message
146+ if ( error . message === ABORT_ERROR_MESSAGE ) {
147+ return true
148+ }
149+ // Check for native AbortError (DOMException or Error with name 'AbortError')
150+ // This is thrown by fetch, AI SDK, and other web APIs when AbortSignal is triggered
151+ if ( error . name === 'AbortError' ) {
152+ return true
153+ }
154+ return false
155+ }
156+
157+ /**
158+ * Unwrap a PromptResult, returning the value if successful or throwing if aborted.
159+ *
160+ * Use this helper for consistent abort handling when you want aborts to propagate
161+ * as exceptions. Callers should use `isAbortError()` in catch blocks to detect
162+ * and handle abort errors appropriately (e.g., rethrow instead of logging as errors).
163+ *
164+ * @throws {Error } When result.aborted is true. The error message is ABORT_ERROR_MESSAGE.
165+ */
166+ export function unwrapPromptResult < T > ( result : PromptResult < T > ) : T {
167+ if ( result . aborted ) {
168+ throw new Error ( ABORT_ERROR_MESSAGE )
169+ }
170+ return result . value
171+ }
172+
53173// Extended error properties that various libraries add to Error objects
54174interface ExtendedErrorProperties {
55175 status ?: number
0 commit comments