From 2904d30a5cf2b9c33437badaa5d42a3ec665d0ed Mon Sep 17 00:00:00 2001 From: Bas van den Aakster Date: Fri, 5 Dec 2025 14:39:52 +0100 Subject: [PATCH] fix: improve error logging with detailed messages and stack traces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, error objects were passed directly to the logger without proper serialization, resulting in empty error messages like "Error:" with no details. This made debugging production issues impossible. Changes: - Extract error message and stack trace before logging - Format errors consistently across all providers - Add stack trace logging for better debugging - Update test provider error handling This fixes the issue where webhook and payment update errors showed no useful information in production logs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- package.json | 2 +- src/providers/test.ts | 3 ++- src/providers/utils.ts | 22 +++++++++++++++++----- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index ef6c34a..f407d1f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@xtr-dev/payload-billing", - "version": "0.1.23", + "version": "0.1.24", "description": "PayloadCMS plugin for billing and payment provider integrations with tracking and local testing", "license": "MIT", "type": "module", diff --git a/src/providers/test.ts b/src/providers/test.ts index 66f9745..11caa6c 100644 --- a/src/providers/test.ts +++ b/src/providers/test.ts @@ -424,7 +424,8 @@ export const testProvider = (testConfig: TestProviderConfig) => { setTimeout(() => { processTestPayment(payload, session, pluginConfig).catch(async (error) => { const logger = createContextLogger(payload, 'Test Provider') - logger.error('Failed to process payment:', error) + const errorMessage = error instanceof Error ? error.message : String(error) + logger.error(`Failed to process payment: ${errorMessage}`) // Ensure session status is updated consistently session.status = 'failed' diff --git a/src/providers/utils.ts b/src/providers/utils.ts index a6e436a..ec27016 100644 --- a/src/providers/utils.ts +++ b/src/providers/utils.ts @@ -16,7 +16,7 @@ export const webhookResponses = { // Log error internally but don't expose details if (payload) { const logger = createContextLogger(payload, 'Webhook') - logger.error('Error:', message) + logger.error(`Error: ${message}`) } else { console.error('[Webhook] Error:', message) } @@ -126,7 +126,12 @@ export async function updatePaymentStatus( } } catch (error) { const logger = createContextLogger(payload, 'Payment Update') - logger.error(`Failed to update payment ${paymentId}:`, error) + const errorMessage = error instanceof Error ? error.message : String(error) + const errorStack = error instanceof Error ? error.stack : undefined + logger.error(`Failed to update payment ${paymentId}: ${errorMessage}`) + if (errorStack) { + logger.error(`Stack trace: ${errorStack}`) + } return false } } @@ -165,15 +170,22 @@ export function handleWebhookError( context?: string, payload?: Payload ): Response { - const message = error instanceof Error ? error.message : 'Unknown error' + const message = error instanceof Error ? error.message : String(error) + const stack = error instanceof Error ? error.stack : undefined const fullContext = context ? `${provider} Webhook - ${context}` : `${provider} Webhook` // Log detailed error internally for debugging if (payload) { const logger = createContextLogger(payload, fullContext) - logger.error('Error:', error) + logger.error(`Error: ${message}`) + if (stack) { + logger.error(`Stack trace: ${stack}`) + } } else { - console.error(`[${fullContext}] Error:`, error) + console.error(`[${fullContext}] Error: ${message}`) + if (stack) { + console.error(`[${fullContext}] Stack trace:`, stack) + } } // Return generic response to avoid information disclosure