feat(web): add ApiErrorBanner retry-capable error card
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
<script lang="ts">
|
||||
import type { ApiError } from '$lib/api/client';
|
||||
|
||||
let {
|
||||
error,
|
||||
onRetry
|
||||
}: { error: unknown; onRetry: () => void } = $props();
|
||||
|
||||
const apiErr = $derived(error as ApiError | undefined);
|
||||
const message = $derived(apiErr?.message ?? 'Something went wrong.');
|
||||
</script>
|
||||
|
||||
<div role="alert" class="rounded border border-danger/40 bg-surface p-4">
|
||||
<p class="text-text-primary">{message}</p>
|
||||
<button
|
||||
type="button"
|
||||
class="mt-2 rounded bg-accent px-3 py-1 text-sm text-background"
|
||||
onclick={onRetry}
|
||||
>
|
||||
Try again
|
||||
</button>
|
||||
</div>
|
||||
@@ -0,0 +1,32 @@
|
||||
import { describe, expect, test, vi } from 'vitest';
|
||||
import { render, screen, fireEvent } from '@testing-library/svelte';
|
||||
import ApiErrorBanner from './ApiErrorBanner.svelte';
|
||||
|
||||
describe('ApiErrorBanner', () => {
|
||||
test('renders error.message when present', () => {
|
||||
render(ApiErrorBanner, {
|
||||
props: {
|
||||
error: { code: 'server_error', message: 'database down', status: 500 },
|
||||
onRetry: () => {}
|
||||
}
|
||||
});
|
||||
expect(screen.getByRole('alert')).toHaveTextContent('database down');
|
||||
});
|
||||
|
||||
test('falls back to generic text when error lacks message', () => {
|
||||
render(ApiErrorBanner, { props: { error: undefined, onRetry: () => {} } });
|
||||
expect(screen.getByRole('alert')).toHaveTextContent(/something went wrong/i);
|
||||
});
|
||||
|
||||
test('clicking the button calls onRetry', async () => {
|
||||
const onRetry = vi.fn();
|
||||
render(ApiErrorBanner, {
|
||||
props: {
|
||||
error: { code: 'server_error', message: 'x', status: 500 },
|
||||
onRetry
|
||||
}
|
||||
});
|
||||
await fireEvent.click(screen.getByRole('button', { name: /try again/i }));
|
||||
expect(onRetry).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user