Files
thrilltrack-explorer/src/lib/errorHandler.ts
2025-10-20 00:26:49 +00:00

93 lines
1.9 KiB
TypeScript

import { toast } from 'sonner';
import { logger } from './logger';
export type ErrorContext = {
action: string;
userId?: string;
metadata?: Record<string, unknown>;
};
export class AppError extends Error {
constructor(
message: string,
public code: string,
public userMessage?: string
) {
super(message);
this.name = 'AppError';
}
}
export const handleError = (
error: unknown,
context: ErrorContext
): void => {
const errorMessage = error instanceof AppError
? error.userMessage || error.message
: error instanceof Error
? error.message
: 'An unexpected error occurred';
// Log to console/monitoring
logger.error('Error occurred', {
...context,
error: error instanceof Error ? error.message : String(error),
stack: error instanceof Error ? error.stack : undefined
});
// Show user-friendly toast
toast.error(context.action, {
description: errorMessage,
duration: 5000
});
};
export const handleSuccess = (
title: string,
description?: string
): void => {
toast.success(title, {
description,
duration: 3000
});
};
export const handleInfo = (
title: string,
description?: string
): void => {
toast.info(title, {
description,
duration: 4000
});
};
/**
* Type-safe error message extraction utility
* Use this instead of `error: any` in catch blocks
*/
export function getErrorMessage(error: unknown): string {
if (error instanceof Error) {
return error.message;
}
if (typeof error === 'string') {
return error;
}
if (error && typeof error === 'object' && 'message' in error) {
return String(error.message);
}
return 'An unexpected error occurred';
}
/**
* Type guard to check if error has a code property
*/
export function hasErrorCode(error: unknown): error is { code: string } {
return (
error !== null &&
typeof error === 'object' &&
'code' in error &&
typeof (error as { code: unknown }).code === 'string'
);
}