ZagoraResult Type
Result type reference
Every Zagora procedure returns a ZagoraResult—a discriminated union representing success or failure.
Type Definition
type ZagoraResult<TData, TErrors = never> =
| { ok: true; data: TData; error: undefined }
| { ok: false; data: undefined; error: ZagoraError<TErrors> };Success Result
When ok is true, the procedure succeeded:
{
ok: true,
data: TData, // Your return value
error: undefined // Always undefined on success
}const result = greet('World');
if (result.ok) {
console.log(result.data); // 'Hello, World!'
console.log(result.error); // undefined
}Error Result
When ok is false, the procedure failed:
{
ok: false,
data: undefined, // Always undefined on error
error: ZagoraError // Typed error object
}const result = divide(10, 0);
if (!result.ok) {
console.log(result.data); // undefined
console.log(result.error); // { kind: 'DIVISION_BY_ZERO', ... }
}Type Narrowing
TypeScript narrows the type based on ok:
const result = proc(input);
if (result.ok) {
// TypeScript knows:
// - result.data is TData
// - result.error is undefined
result.data.someProperty; // OK
} else {
// TypeScript knows:
// - result.data is undefined
// - result.error is ZagoraError<TErrors>
result.error.kind; // OK
}Async Results
Async procedures return Promise<ZagoraResult>:
const asyncProc = zagora()
.handler(async () => fetchData())
.callable();
const result = await asyncProc();
// result: ZagoraResult<Data>Generic Parameters
TData
The success data type, inferred from:
- Output schema (if defined)
- Handler return type (otherwise)
// From output schema
zagora()
.output(z.object({ id: z.string() }))
.handler(() => ({ id: '123' }))
// TData = { id: string }
// From handler return
zagora()
.handler(() => ({ id: '123', name: 'test' }))
// TData = { id: string, name: string }TErrors
The union of possible error types:
zagora()
.errors({
NOT_FOUND: z.object({ id: z.string() }),
FORBIDDEN: z.object({ reason: z.string() })
})
// TErrors =
// | { kind: 'NOT_FOUND', id: string }
// | { kind: 'FORBIDDEN', reason: string }
// | ValidationError
// | UnknownErrorUtility Types
Extracting Data Type
import type { ZagoraResult } from 'zagora/types';
type Result = ZagoraResult<{ id: string }, never>;
// Extract data type
type Data = Extract<Result, { ok: true }>['data'];
// Data = { id: string }Extracting Error Type
type ErrorType = Extract<Result, { ok: false }>['error'];Pattern: Result Handling
Basic Pattern
const result = proc(input);
if (result.ok) {
return result.data;
} else {
throw new Error(result.error.message);
}Switch on Error Kind
if (!result.ok) {
switch (result.error.kind) {
case 'NOT_FOUND':
return { status: 404, body: result.error };
case 'FORBIDDEN':
return { status: 403, body: result.error };
case 'VALIDATION_ERROR':
return { status: 400, body: result.error.issues };
case 'UNKNOWN_ERROR':
console.error(result.error.cause);
return { status: 500, body: 'Internal error' };
}
}Generic Result Handler
function handleResult<T>(result: ZagoraResult<T, any>): T {
if (result.ok) {
return result.data;
}
// Log and re-throw as appropriate for your app
console.error('Procedure failed:', result.error);
throw new Error(`${result.error.kind}: ${result.error.message}`);
}
const data = handleResult(proc(input));See Also
- Error Types - All error types
- Never-Throwing Guarantees - Why results never throw