Error Handling & Responses
Section titled “Error Handling & Responses”Error Handling and Token Refresh
Section titled “Error Handling and Token Refresh”The BridgeAuthGuard returns RFC 6750-compliant WWW-Authenticate response headers so your frontend can distinguish between error types and handle them appropriately.
Error codes
Section titled “Error codes”| WWW-Authenticate error | Meaning | Recommended action |
|---|---|---|
| missing_token | No Authorization header was sent | Redirect to sign-in |
| expired_token | Token signature is valid but past expiry | Attempt silent refresh, then redirect |
| invalid_token | Token is malformed, tampered, or uses an unknown key | Redirect to sign-in |
Frontend auto-refresh pattern
Section titled “Frontend auto-refresh pattern”This example uses the auth object from @nebulr-group/bridge-svelte (a lazy proxy to the BridgeAuth singleton); @nebulr-group/bridge-react exposes the same capabilities through its useBridgeToken() hook (getAccessToken, login, logout).
// src/lib/api.ts
import { auth } from '@nebulr-group/bridge-svelte';
async function apiFetch(endpoint: string, options: RequestInit = {}) {
const token = auth.getTokens()?.accessToken;
const response = await fetch(`http://localhost:3000${endpoint}`, {
...options,
headers: {
...options.headers,
...(token ? { Authorization: `Bearer ${token}` } : {}),
'Content-Type': 'application/json',
},
});
if (response.status === 401) {
const wwwAuth = response.headers.get('WWW-Authenticate') ?? '';
if (wwwAuth.includes('expired_token')) {
try {
await auth.refreshTokens();
const newToken = auth.getTokens()?.accessToken;
return fetch(`http://localhost:3000${endpoint}`, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${newToken}`,
'Content-Type': 'application/json',
},
}).then((r) => r.json());
} catch {
await auth.login();
return;
}
}
// missing_token or invalid_token: send the user back to sign in
await auth.login();
return;
}
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
return response.json();
}
Error Responses
Section titled “Error Responses”401 Unauthorized
Section titled “401 Unauthorized”Returned when token is missing, expired, or invalid. Includes RFC 6750 WWW-Authenticate header:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="expired_token", error_description="The access token has expired"
{
"statusCode": 401,
"error": "Unauthorized",
"message": "The access token has expired"
}
Auth type rejection (e.g., API token sent to a @AcceptAuth('jwt') endpoint):
{
"statusCode": 401,
"error": "Unauthorized",
"message": "auth type not accepted"
}
403 Forbidden
Section titled “403 Forbidden”Returned when authenticated but lacking required role, privilege, or feature flag:
Role check failed:
{
"statusCode": 403,
"error": "Forbidden",
"message": "Role 'ADMIN' required"
}
Privilege check failed:
{
"statusCode": 403,
"error": "Forbidden",
"message": "Privilege 'USER_READ' required"
}
Feature flag not enabled:
{
"statusCode": 403,
"error": "Forbidden",
"message": "Feature flag 'beta-access' is not enabled"
}
TokenVerificationError
Section titled “TokenVerificationError”Thrown by JwksService when token verification fails. Error codes:
| Code | Meaning |
|------|---------|
| TOKEN_EXPIRED | JWT has expired |
| TOKEN_INVALID | JWT is malformed or invalid; on the API-token path, introspection reported the token inactive (revoked, expired, forged) or not an API token |
| JWKS_NO_MATCH | No matching key found in JWKS endpoint |
| CLAIM_VALIDATION_FAILED | Token claim validation failed (e.g., wrong issuer or audience) |
| APP_MISMATCH | API token was issued for a different app ID |
| UNKNOWN_ERROR | Unexpected verification error (including a failed introspection request) |
These are mapped to RFC 6750 WWW-Authenticate errors by the guard:
| Error Code | RFC 6750 Error | Description |
|------------|----------------|-------------|
| TOKEN_EXPIRED | expired_token | The access token has expired |
| TOKEN_INVALID | invalid_token | The access token is invalid |
| JWKS_NO_MATCH | invalid_token | The access token signature could not be verified |
| CLAIM_VALIDATION_FAILED | invalid_token | The access token claim validation failed |
| APP_MISMATCH | invalid_token | The access token was issued for a different application |
BridgeHttpError
Section titled “BridgeHttpError”Thrown by BridgeHttpService when a downstream HTTP call returns a non-2xx response:
class BridgeHttpError extends Error {
readonly status: number; // HTTP status code
readonly url: string; // Request URL
}
try {
await this.bridgeHttp.get('http://service-b/data', token);
} catch (error) {
if (error instanceof BridgeHttpError) {
console.log(error.status); // e.g., 404
console.log(error.url); // 'http://service-b/data'
}
}