Error Handling
Structured error handling for App Functions with semantic error codes.
FunctionError
Throw FunctionError in your function handlers to return structured error responses:
import { FunctionError } from '@edgebase/shared';
export const POST = defineFunction(async ({ auth, admin }) => {
if (!auth) {
throw new FunctionError('unauthenticated', 'Login required');
}
if (auth.custom?.role !== 'admin') {
throw new FunctionError('permission-denied', 'Admin access required');
}
const user = await admin.db('shared').table('users').get(auth.id);
if (!user) {
throw new FunctionError('not-found', 'User not found');
}
// Check preconditions before proceeding
if (user.status !== 'active') {
throw new FunctionError('failed-precondition', 'Account must be active to perform this action');
// Returns HTTP 412 Precondition Failed
}
return user;
});
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
unauthenticated | 401 | No auth token or invalid token |
permission-denied | 403 | Authenticated but not authorized |
not-found | 404 | Resource not found |
invalid-argument | 400 | Bad request parameters |
already-exists | 409 | Resource already exists |
resource-exhausted | 429 | Rate limit exceeded |
failed-precondition | 412 | Operation prerequisites not met |
internal | 500 | Internal server error |
unavailable | 503 | Service temporarily unavailable |
Error Response Format
When a FunctionError is thrown, the client receives:
{
"code": "permission-denied",
"message": "Admin access required",
"status": 403
}
Error Details
Pass additional context with the details parameter:
throw new FunctionError('invalid-argument', 'Validation failed', {
field: 'email',
reason: 'Invalid email format',
});
Response:
{
"code": "invalid-argument",
"message": "Validation failed",
"status": 400,
"details": { "field": "email", "reason": "Invalid email format" }
}
Client-Side Handling
Errors thrown by functions are caught as EdgeBaseError in the client SDK:
import { EdgeBaseError } from '@edgebase/web';
try {
await client.functions.post('create-order', { items: [] });
} catch (err) {
if (err instanceof EdgeBaseError) {
switch (err.code) {
case 401: // unauthenticated
redirectToLogin();
break;
case 403: // permission-denied
showAccessDenied();
break;
default:
showError(err.message);
}
}
}
Unhandled Errors
If a function throws a non-FunctionError error (e.g., throw new Error(...)), the server returns a generic 500 response. The actual error message is logged server-side but not exposed to the client for security.