feat(error): add error handling foundation (Day 0)
- extractErrorMessage(err: unknown) normalizes any error shape to string - handleError/handleInfraError dual utilities (user-facing vs infra-only) - error-classifier extended with ipc/database/filesystem types (9 total) - Toast rate-limiting (max 3 per type per 30s) in notifications store - Infrastructure bridges use documented console.warn (recursion prevention) - 13 new tests for extractErrorMessage
This commit is contained in:
parent
bfc01192d2
commit
dcdb741403
7 changed files with 215 additions and 4 deletions
26
src/lib/utils/extract-error-message.ts
Normal file
26
src/lib/utils/extract-error-message.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Extract a human-readable message from any error shape
|
||||
|
||||
/**
|
||||
* Normalize any caught error value into a readable string.
|
||||
* Handles: string, Error, Tauri IPC errors, Rust AppError {kind, detail}, objects with .message.
|
||||
*/
|
||||
export function extractErrorMessage(err: unknown): string {
|
||||
if (typeof err === 'string') return err;
|
||||
if (err instanceof Error) return err.message;
|
||||
if (err && typeof err === 'object') {
|
||||
const obj = err as Record<string, unknown>;
|
||||
// Rust AppError tagged enum: { kind: "Database", detail: { ... } }
|
||||
if ('kind' in obj && typeof obj.kind === 'string') {
|
||||
if ('detail' in obj && obj.detail) {
|
||||
const detail = typeof obj.detail === 'string'
|
||||
? obj.detail
|
||||
: JSON.stringify(obj.detail);
|
||||
return `${obj.kind}: ${detail}`;
|
||||
}
|
||||
return obj.kind;
|
||||
}
|
||||
// Generic object with message property
|
||||
if ('message' in obj && typeof obj.message === 'string') return obj.message;
|
||||
}
|
||||
return String(err);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue