48 lines
1.1 KiB
TypeScript
48 lines
1.1 KiB
TypeScript
export const KNOWN_ERROR_CODES = [
|
|
'missing_permission',
|
|
'escalation',
|
|
'role_locked',
|
|
'own_role',
|
|
'role_built_in',
|
|
'built_in_name',
|
|
'role_conflict',
|
|
'user_role_changed',
|
|
'session_required',
|
|
] as const
|
|
|
|
export type ApiErrorCode = (typeof KNOWN_ERROR_CODES)[number]
|
|
|
|
export interface ApiErrorDetails {
|
|
code?: ApiErrorCode
|
|
permission?: string
|
|
escalationKey?: string
|
|
}
|
|
|
|
const SESSION_REQUIRED_MESSAGE = 'This action needs a real session.'
|
|
|
|
export function errorCodeOf(body: string | undefined): ApiErrorCode | undefined {
|
|
if (body === SESSION_REQUIRED_MESSAGE) {
|
|
return 'session_required'
|
|
}
|
|
return KNOWN_ERROR_CODES.find((code) => code === body)
|
|
}
|
|
|
|
export class ApiError extends Error {
|
|
status: number
|
|
retryAfter?: number
|
|
body?: string
|
|
code?: ApiErrorCode
|
|
permission?: string
|
|
escalationKey?: string
|
|
|
|
constructor(status: number, retryAfter?: number, body?: string, details: ApiErrorDetails = {}) {
|
|
super(`Request failed with status ${status}`)
|
|
this.status = status
|
|
this.retryAfter = retryAfter
|
|
this.body = body
|
|
this.code = details.code
|
|
this.permission = details.permission
|
|
this.escalationKey = details.escalationKey
|
|
}
|
|
}
|