mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 08:51:13 -05:00
Implement client-side error timing
This commit is contained in:
@@ -57,8 +57,7 @@ Timestamp: ${format(new Date(error.created_at), 'PPpp')}
|
||||
Type: ${error.error_type}
|
||||
Endpoint: ${error.endpoint}
|
||||
Method: ${error.method}
|
||||
Status: ${error.status_code}
|
||||
Duration: ${error.duration_ms}ms
|
||||
Status: ${error.status_code}${error.duration_ms != null ? `\nDuration: ${error.duration_ms}ms` : ''}
|
||||
|
||||
Error Message:
|
||||
${error.error_message}
|
||||
@@ -117,10 +116,12 @@ ${error.error_stack ? `Stack Trace:\n${error.error_stack}` : ''}
|
||||
<label className="text-sm font-medium">Status Code</label>
|
||||
<p className="text-sm">{error.status_code}</p>
|
||||
</div>
|
||||
{error.duration_ms != null && (
|
||||
<div>
|
||||
<label className="text-sm font-medium">Duration</label>
|
||||
<p className="text-sm">{error.duration_ms}ms</p>
|
||||
</div>
|
||||
)}
|
||||
{error.user_id && (
|
||||
<div>
|
||||
<label className="text-sm font-medium">User ID</label>
|
||||
|
||||
@@ -8,6 +8,7 @@ export type ErrorContext = {
|
||||
action: string;
|
||||
userId?: string;
|
||||
metadata?: Record<string, unknown>;
|
||||
duration?: number; // Optional: milliseconds the operation took
|
||||
};
|
||||
|
||||
export class AppError extends Error {
|
||||
@@ -78,6 +79,7 @@ export const handleError = (
|
||||
p_breadcrumbs: JSON.stringify(breadcrumbs),
|
||||
p_timezone: envContext.timezone,
|
||||
p_referrer: document.referrer || undefined,
|
||||
p_duration_ms: context.duration,
|
||||
}).then(({ error: dbError }) => {
|
||||
if (dbError) {
|
||||
logger.error('Failed to log error to database', { dbError });
|
||||
@@ -161,6 +163,7 @@ export const handleNonCriticalError = (
|
||||
p_breadcrumbs: JSON.stringify(breadcrumbs),
|
||||
p_timezone: envContext.timezone,
|
||||
p_referrer: document.referrer || undefined,
|
||||
p_duration_ms: context.duration,
|
||||
}).then(({ error: dbError }) => {
|
||||
if (dbError) {
|
||||
logger.error('Failed to log non-critical error to database', { dbError });
|
||||
@@ -202,3 +205,21 @@ export function hasErrorCode(error: unknown): error is { code: string } {
|
||||
typeof (error as { code: unknown }).code === 'string'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to wrap async operations with automatic duration tracking
|
||||
* Use this for operations where you want to track how long they took before failing
|
||||
*/
|
||||
export async function withErrorTiming<T>(
|
||||
fn: () => Promise<T>,
|
||||
errorContext: Omit<ErrorContext, 'duration'>
|
||||
): Promise<T> {
|
||||
const start = performance.now();
|
||||
try {
|
||||
return await fn();
|
||||
} catch (error) {
|
||||
const duration = Math.round(performance.now() - start);
|
||||
handleError(error, { ...errorContext, duration });
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ export default function ErrorMonitoring() {
|
||||
<div className="flex items-center gap-4 text-xs text-muted-foreground">
|
||||
<span>ID: {error.request_id.slice(0, 8)}</span>
|
||||
<span>{format(new Date(error.created_at), 'PPp')}</span>
|
||||
<span>{error.duration_ms}ms</span>
|
||||
{error.duration_ms != null && <span>{error.duration_ms}ms</span>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user