2 Commits

Author SHA1 Message Date
2904d30a5c fix: improve error logging with detailed messages and stack traces
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 <noreply@anthropic.com>
2025-12-05 14:39:52 +01:00
bf6f546371 fix: handle missing toPlainObject in Mollie client responses
Add fallback for Mollie API responses that may not have toPlainObject method
depending on client version or response type.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 21:16:45 +01:00
4 changed files with 29 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@xtr-dev/payload-billing",
"version": "0.1.22",
"version": "0.1.24",
"description": "PayloadCMS plugin for billing and payment provider integrations with tracking and local testing",
"license": "MIT",
"type": "module",

View File

@@ -85,11 +85,15 @@ export const mollieProvider = (mollieConfig: MollieProviderConfig & {
const status = mapMollieStatusToPaymentStatus(molliePayment.status)
// Update the payment status and provider data
// Use toPlainObject if available, otherwise spread the object
const providerData = typeof molliePayment.toPlainObject === 'function'
? molliePayment.toPlainObject()
: { ...molliePayment }
const updateSuccess = await updatePaymentStatus(
payload,
payment.id,
status,
molliePayment.toPlainObject(),
providerData,
pluginConfig
)
@@ -167,7 +171,10 @@ export const mollieProvider = (mollieConfig: MollieProviderConfig & {
webhookUrl,
});
payment.providerId = molliePayment.id
payment.providerData = molliePayment.toPlainObject()
// Use toPlainObject if available, otherwise spread the object (for compatibility with different Mollie client versions)
payment.providerData = typeof molliePayment.toPlainObject === 'function'
? molliePayment.toPlainObject()
: { ...molliePayment }
payment.checkoutUrl = molliePayment._links?.checkout?.href || null
return payment
},

View File

@@ -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'

View File

@@ -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