Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions server/utils/error-handler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isError, createError } from 'h3'
import { FetchError } from 'ofetch'
import * as v from 'valibot'
import type { ErrorOptions } from '#shared/types/error'

Expand All @@ -18,6 +19,13 @@ export function handleApiError(error: unknown, fallback: ErrorOptions): never {
throw error
}

if (error instanceof FetchError && error.statusCode) {
throw createError({
statusCode: error.statusCode,
message: error.statusMessage,
})
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// Handle Valibot validation errors
if (v.isValiError(error)) {
throw createError({
Expand Down
31 changes: 31 additions & 0 deletions test/unit/server/utils/error-handler.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, expect, it } from 'vitest'
import { createError } from 'h3'
import { FetchError } from 'ofetch'
import * as v from 'valibot'
import { handleApiError } from '../../../../server/utils/error-handler'

Expand Down Expand Up @@ -44,4 +45,34 @@ describe('handleApiError', () => {
expect.objectContaining({ statusCode: 503, message: 'Service unavailable' }),
)
})

describe('FetchError handling', () => {
it('propagates the upstream statusCode from a FetchError', () => {
const fetchErr = new FetchError('Not Found')
fetchErr.statusCode = 404
fetchErr.statusMessage = 'Not Found'

expect(() => handleApiError(fetchErr, fallback)).toThrow(
expect.objectContaining({ statusCode: 404, message: 'Not Found' }),
)
})

it('propagates a 503 statusCode from a FetchError', () => {
const fetchErr = new FetchError('Service Unavailable')
fetchErr.statusCode = 503
fetchErr.statusMessage = 'Service Unavailable'

expect(() => handleApiError(fetchErr, fallback)).toThrow(
expect.objectContaining({ statusCode: 503 }),
)
})

it('falls through to the generic fallback when FetchError has no statusCode', () => {
const fetchErr = new FetchError('Network error')

expect(() => handleApiError(fetchErr, { message: 'Bad gateway', statusCode: 502 })).toThrow(
expect.objectContaining({ statusCode: 502, message: 'Bad gateway' }),
)
})
})
})
Loading