refactor(frontend): improve code quality and maintainability
- Extract API error handling utility (utils/error-handling.ts) - Centralize error message extraction logic - Add type guards for API errors - Replace duplicated error handling across components - Create reusable Toast component (components/Toast.tsx) - Extract toast notification logic from profile page - Support auto-dismiss functionality - Consistent styling with shared styles - Extract form validation debouncing hook (hooks/useDebouncedValidation.ts) - Reusable debounced validation logic - Clean timeout management - Used in profile page for form validation - Consolidate duplicate styles (styles/auth-form.ts) - Use shared style tokens instead of duplicating values - Reduce code duplication between auth-form and shared styles - Extract loading state component (components/LoadingState.tsx) - Standardize loading UI across pages - Replace duplicated loading JSX patterns - Used in profile, exchange, and trades pages - Fix useRequireAuth dependency array - Remove unnecessary hasPermission from dependencies - Add eslint-disable comment with explanation - Improve hook stability and performance All frontend tests pass. Linting passes.
This commit is contained in:
parent
db181b338c
commit
3beb23a765
10 changed files with 231 additions and 143 deletions
50
frontend/app/utils/error-handling.ts
Normal file
50
frontend/app/utils/error-handling.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import { ApiError } from "../api";
|
||||
|
||||
/**
|
||||
* Extract a user-friendly error message from an API error or generic error.
|
||||
* Handles ApiError instances with structured data, regular Error instances, and unknown errors.
|
||||
*
|
||||
* @param err - The error to extract a message from
|
||||
* @param fallback - Default message if extraction fails (default: "An error occurred")
|
||||
* @returns A user-friendly error message string
|
||||
*/
|
||||
export function extractApiErrorMessage(
|
||||
err: unknown,
|
||||
fallback: string = "An error occurred"
|
||||
): string {
|
||||
if (err instanceof ApiError) {
|
||||
if (err.data && typeof err.data === "object") {
|
||||
const data = err.data as { detail?: string };
|
||||
return data.detail || err.message || fallback;
|
||||
}
|
||||
return err.message || fallback;
|
||||
}
|
||||
if (err instanceof Error) {
|
||||
return err.message;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard to check if an error is an ApiError with structured detail data.
|
||||
*/
|
||||
export function isApiErrorWithDetail(
|
||||
err: unknown
|
||||
): err is ApiError & { data: { detail?: string } } {
|
||||
return err instanceof ApiError && err.data !== undefined && typeof err.data === "object";
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract field errors from a 422 validation error response.
|
||||
* Returns undefined if the error doesn't contain field errors.
|
||||
*/
|
||||
export function extractFieldErrors(
|
||||
err: unknown
|
||||
): { detail?: { field_errors?: Record<string, string> } } | undefined {
|
||||
if (err instanceof ApiError && err.status === 422) {
|
||||
if (err.data && typeof err.data === "object") {
|
||||
return err.data as { detail?: { field_errors?: Record<string, string> } };
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue