LakeQL normalizes errors end to end. Adapters throw typed DataSourceErrors. The API maps them to GraphQL errors with a stable code and HTTP status, logs them server-side, and offers a hook to forward them to telemetry.
Error Mapping #
handleErrorResponse maps a DataSourceError to a GraphQLError by its category:
category | Code | HTTP status |
|---|---|---|
auth | PERMISSION_DENIED | 403 |
query | QUERY_ERROR | 400 |
network | NETWORK_ERROR | 502 |
timeout | TIMEOUT | 504 |
cancelled | CANCELLED | 499 |
unsupported | UNSUPPORTED_OPERATION | 400 |
| anything else | UNKNOWN | 500 |
Errors that are not a DataSourceError fall through to the UNKNOWN / 500 branch. This includes DataSourceValidationError, which is a plain Error subclass.
The original error is preserved on the GraphQL error so server-side logging and telemetry keep the full context.
Server-Side Logging #
A built-in Yoga plugin logs every execution error with a severity matched to its category. Network and timeout errors log at error level, auth and query errors at warn, and anything that is not a DataSourceError at error. This runs regardless of what the client sees, so operational issues stay visible in your logs.
The onError Hook #
Forward errors to external telemetry like OpenTelemetry, Sentry, or metrics without the package depending on any of them. Provide an onError hook on defineApiConfig:
1
2
3
4
5
6
7
8
const server = defineApiConfig({
runtime,
tokenResolver,
onError: ({ error }) => {
telemetry.recordException(error)
},
})
The hook runs for every execution error after it is logged. Errors thrown by the hook itself are swallowed, so a telemetry failure never breaks a response. See ApiErrorHook and createErrorLoggingPlugin.