85 lines
2.7 KiB
TypeScript
85 lines
2.7 KiB
TypeScript
import { describe, expect, test } from 'vitest';
|
|
import {
|
|
ServerAppError,
|
|
createServerAppError,
|
|
isServerAppError,
|
|
normalizeServerError,
|
|
toApiErrorBody,
|
|
toHttpStatus,
|
|
} from '../../src/lib/server/errors/contract';
|
|
import { makeServerAppErrorInput } from './support/factories';
|
|
|
|
describe('server error contract', () => {
|
|
test('normalizes unknown throwable to fallback shape', () => {
|
|
const normalized = normalizeServerError('boom');
|
|
|
|
expect(normalized.code).toBe('UNKNOWN_SERVER_ERROR');
|
|
expect(normalized.errorClass).toBe('unknown');
|
|
expect(normalized.httpStatus).toBe(500);
|
|
expect(normalized.retryable).toBe(false);
|
|
expect(normalized.message).toBe('boom');
|
|
});
|
|
|
|
test('preserves ServerAppError metadata', () => {
|
|
const err = createServerAppError(makeServerAppErrorInput({
|
|
code: 'USER_PROGRESS_UPDATE_FAILED',
|
|
message: 'Failed to update progress',
|
|
errorClass: 'db',
|
|
retryable: true,
|
|
httpStatus: 500,
|
|
details: { operation: 'update_progress' },
|
|
}));
|
|
|
|
const normalized = normalizeServerError(err);
|
|
|
|
expect(isServerAppError(err)).toBe(true);
|
|
expect(normalized.code).toBe('USER_PROGRESS_UPDATE_FAILED');
|
|
expect(normalized.errorClass).toBe('db');
|
|
expect(normalized.httpStatus).toBe(500);
|
|
expect(normalized.retryable).toBe(true);
|
|
expect(normalized.details?.operation).toBe('update_progress');
|
|
});
|
|
|
|
test('normalizes partially-shaped thrown errors with code sanitization', () => {
|
|
const thrown = Object.assign(new Error('Timed out waiting for storage read'), {
|
|
code: 'not_valid_code',
|
|
errorClass: 'timeout',
|
|
httpStatus: 604,
|
|
retryable: true,
|
|
});
|
|
|
|
const normalized = normalizeServerError(thrown);
|
|
|
|
expect(normalized.code).toBe('UNKNOWN_SERVER_ERROR');
|
|
expect(normalized.errorClass).toBe('timeout');
|
|
expect(normalized.httpStatus).toBe(599);
|
|
expect(normalized.retryable).toBe(true);
|
|
});
|
|
|
|
test('maps normalized errors to API body + status', () => {
|
|
const normalized = normalizeServerError(
|
|
new ServerAppError({
|
|
code: 'UPSTREAM_TTS_ERROR',
|
|
message: 'Upstream failure',
|
|
errorClass: 'upstream',
|
|
}),
|
|
);
|
|
|
|
const body = toApiErrorBody(normalized, { includeDetails: false });
|
|
|
|
expect(body).toEqual({
|
|
error: 'Upstream failure',
|
|
errorCode: 'UPSTREAM_TTS_ERROR',
|
|
retryable: true,
|
|
});
|
|
expect(toHttpStatus(normalized)).toBe(502);
|
|
});
|
|
|
|
test('rejects invalid server error code at creation boundary', () => {
|
|
expect(() => createServerAppError(makeServerAppErrorInput({
|
|
code: 'bad-code',
|
|
message: 'Invalid',
|
|
errorClass: 'validation',
|
|
}))).toThrow(/Invalid ServerAppError code/i);
|
|
});
|
|
});
|