Connect to Lovable Cloud

Add centralized errorFormatter to convert various error types into readable messages, and apply it across edge functions. Replace String(error) usage with formatEdgeError, update relevant imports, fix a throw to use toError, and enhance logger to log formatted errors. Includes new errorFormatter.ts and widespread updates to 18+ edge functions plus logger integration.
This commit is contained in:
gpt-engineer-app[bot]
2025-11-10 18:09:15 +00:00
parent 4a18462c37
commit 2d65f13b85
20 changed files with 152 additions and 37 deletions

View File

@@ -0,0 +1,94 @@
/**
* Error Formatting Utility for Edge Functions
*
* Provides robust error message extraction from various error types:
* - Standard Error objects
* - Supabase PostgresError objects (plain objects with message/details/code/hint)
* - Raw objects and primitives
*
* Eliminates "[object Object]" errors by properly extracting error details.
*/
/**
* Format error objects for logging
* Handles Error objects, Supabase errors (plain objects), and primitives
*
* @param error - Any error value
* @returns Formatted, human-readable error message string
*/
export function formatEdgeError(error: unknown): string {
// Standard Error objects
if (error instanceof Error) {
return error.message;
}
// Object-like errors (Supabase PostgresError, etc.)
if (typeof error === 'object' && error !== null) {
const err = error as any;
// Try common error message properties
if (err.message && typeof err.message === 'string') {
// Include additional Supabase error details if present
const parts: string[] = [err.message];
if (err.details && typeof err.details === 'string') {
parts.push(`Details: ${err.details}`);
}
if (err.hint && typeof err.hint === 'string') {
parts.push(`Hint: ${err.hint}`);
}
if (err.code && typeof err.code === 'string') {
parts.push(`Code: ${err.code}`);
}
return parts.join(' | ');
}
// Some errors nest the actual error in an 'error' property
if (err.error) {
return formatEdgeError(err.error);
}
// Some APIs use 'msg' instead of 'message'
if (err.msg && typeof err.msg === 'string') {
return err.msg;
}
// Last resort: stringify the entire object
try {
const stringified = JSON.stringify(error, null, 2);
return stringified.length > 500
? stringified.substring(0, 500) + '... (truncated)'
: stringified;
} catch {
// JSON.stringify can fail on circular references
return 'Unknown error (could not stringify)';
}
}
// Primitive values (strings, numbers, etc.)
return String(error);
}
/**
* Convert any error to a proper Error instance
* Use this before throwing to ensure proper stack traces
*
* @param error - Any error value
* @returns Error instance with formatted message
*/
export function toError(error: unknown): Error {
if (error instanceof Error) {
return error;
}
const message = formatEdgeError(error);
const newError = new Error(message);
// Preserve original error as property for debugging
(newError as any).originalError = error;
return newError;
}

View File

@@ -3,6 +3,8 @@
* Prevents sensitive data exposure and provides consistent log format
*/
import { formatEdgeError } from './errorFormatter.ts';
type LogLevel = 'info' | 'warn' | 'error' | 'debug';
interface LogContext {
@@ -96,16 +98,17 @@ export function startSpan(
/**
* End a span with final status
*/
export function endSpan(span: Span, status?: 'ok' | 'error', error?: Error): Span {
export function endSpan(span: Span, status?: 'ok' | 'error', error?: unknown): Span {
span.endTime = Date.now();
span.duration = span.endTime - span.startTime;
span.status = status || 'ok';
if (error) {
const err = error instanceof Error ? error : new Error(formatEdgeError(error));
span.error = {
type: error.name,
message: error.message,
stack: error.stack,
type: err.name,
message: err.message,
stack: err.stack,
};
}