diff --git a/apps/taxes/src/modules/app/webhook-response.ts b/apps/taxes/src/modules/app/webhook-response.ts index ffe6ee8..b087407 100644 --- a/apps/taxes/src/modules/app/webhook-response.ts +++ b/apps/taxes/src/modules/app/webhook-response.ts @@ -1,41 +1,7 @@ import { NextApiResponse } from "next"; -import { AvalaraError } from "avatax/lib/AvaTaxClient"; -import { ZodError } from "zod"; import { createLogger, Logger } from "../../lib/logger"; - -class WebhookErrorResolver { - private logger: Logger; - constructor() { - this.logger = createLogger({ event: "WebhookErrorResolver" }); - } - - private resolveErrorMessage(error: unknown) { - if (error instanceof ZodError) { - this.logger.error(error.message, "Unexpected Zod error caught:"); - this.logger.debug(error.stack, "Error details:"); - return error.message; - } - - if (error instanceof AvalaraError) { - this.logger.error(error.message, "Unexpected Avalara error caught:"); - this.logger.debug(error.stack, "Error stack:"); - this.logger.debug(error.target, "Error target:"); - return error.message; - } - - if (error instanceof Error) { - this.logger.error(error.stack, "Unexpected error caught:"); - return error.message; - } - - return "Internal server error"; - } - - resolve(error: unknown) { - return this.resolveErrorMessage(error); - } -} +import { TaxBadWebhookPayloadError, TaxCriticalError } from "../taxes/tax-error"; export class WebhookResponse { private logger: Logger; @@ -43,15 +9,30 @@ export class WebhookResponse { this.logger = createLogger({ event: "WebhookResponse" }); } - error(error: unknown) { - const errorResolver = new WebhookErrorResolver(); - const errorMessage = errorResolver.resolve(error); - - this.logger.debug({ errorMessage }, "Responding to Saleor with error:"); + private respondWithBadRequest(errorMessage: string) { + // Are we sure its 400? + return this.res.status(400).json({ error: errorMessage }); + } + private respondWithInternalServerError(errorMessage: string) { return this.res.status(500).json({ error: errorMessage }); } + error(error: unknown) { + if (error instanceof TaxBadWebhookPayloadError) { + this.logger.warn({ error }, "TaxBadWebhookPayloadError occurred"); + return this.respondWithBadRequest(error.message); + } + + if (error instanceof TaxCriticalError) { + this.logger.error({ error }, "TaxCriticalError occurred"); + return this.respondWithInternalServerError(error.message); + } + + this.logger.error({ error }, "Unexpected error occurred"); + return this.respondWithInternalServerError("Unexpected error occurred"); + } + success(data?: unknown) { return this.res.status(200).json(data ?? {}); } diff --git a/apps/taxes/src/modules/avatax/calculate-taxes/avatax-calculate-taxes-payload-transformer.ts b/apps/taxes/src/modules/avatax/calculate-taxes/avatax-calculate-taxes-payload-transformer.ts index c2957a0..fc3b02c 100644 --- a/apps/taxes/src/modules/avatax/calculate-taxes/avatax-calculate-taxes-payload-transformer.ts +++ b/apps/taxes/src/modules/avatax/calculate-taxes/avatax-calculate-taxes-payload-transformer.ts @@ -1,7 +1,7 @@ import { DocumentType } from "avatax/lib/enums/DocumentType"; import { CalculateTaxesPayload } from "../../../pages/api/webhooks/checkout-calculate-taxes"; import { discountUtils } from "../../taxes/discount-utils"; -import { TaxUnknownError } from "../../taxes/tax-error"; +import { TaxUnexpectedError } from "../../taxes/tax-error"; import { taxProviderUtils } from "../../taxes/tax-provider-utils"; import { avataxAddressFactory } from "../address-factory"; import { AvataxClient, CreateTransactionArgs } from "../avatax-client"; @@ -31,7 +31,7 @@ export class AvataxCalculateTaxesPayloadTransformer { return taxProviderUtils.resolveStringOrThrow(payload.taxBase.sourceObject.userEmail); } - throw new TaxUnknownError("Cannot resolve customer code"); + throw new TaxUnexpectedError("Cannot resolve customer code"); } async transform( diff --git a/apps/taxes/src/modules/taxes/tax-error.ts b/apps/taxes/src/modules/taxes/tax-error.ts index 0848ff0..a8ac37a 100644 --- a/apps/taxes/src/modules/taxes/tax-error.ts +++ b/apps/taxes/src/modules/taxes/tax-error.ts @@ -2,11 +2,17 @@ import { BaseError } from "../../error"; const TaxError = BaseError.subclass("TaxError"); -// An error that we didn't catch -export const TaxUnknownError = TaxError.subclass("TaxUnknownError"); +/* + * Errors that happen if there is not enough data in webhook payload to proceed with the process. Is not reported. + * Better name: BadRequestError? + */ +export const TaxBadWebhookPayloadError = TaxError.subclass("TaxBadWebhookPayloadError"); -// An error that we throw because we know it will happen -export const TaxKnownError = TaxError.subclass("TaxKnownError"); +// Breaks the process. Is reported. +export const TaxCriticalError = TaxError.subclass("TaxCriticalError"); -// An error that we throw but it shouldn't happen -export const TaxUnexpectedError = TaxError.subclass("TaxUnexpectedError"); +// Error that shouldn't happen. Should provide extra insights for debugging. +export const TaxUnexpectedError = TaxCriticalError.subclass("TaxUnexpectedError"); + +// Error that happens when external service returns an error +export const TaxExternalError = TaxCriticalError.subclass("TaxExternalError"); diff --git a/apps/taxes/src/pages/api/webhooks/checkout-calculate-taxes.ts b/apps/taxes/src/pages/api/webhooks/checkout-calculate-taxes.ts index 3cd1956..ff4d89f 100644 --- a/apps/taxes/src/pages/api/webhooks/checkout-calculate-taxes.ts +++ b/apps/taxes/src/pages/api/webhooks/checkout-calculate-taxes.ts @@ -7,6 +7,7 @@ import { saleorApp } from "../../../../saleor-app"; import { createLogger } from "../../../lib/logger"; import { WebhookResponse } from "../../../modules/app/webhook-response"; import { getActiveConnectionService } from "../../../modules/taxes/get-active-connection-service"; +import { TaxBadWebhookPayloadError } from "../../../modules/taxes/tax-error"; export const config = { api: { @@ -21,11 +22,11 @@ export type CalculateTaxesPayload = Extract< function verifyCalculateTaxesPayload(payload: CalculateTaxesPayload) { if (!payload.taxBase.lines.length) { - throw new Error("No lines found in taxBase"); + throw new TaxBadWebhookPayloadError("No lines found in taxBase"); } if (!payload.taxBase.address) { - throw new Error("No address found in taxBase"); + throw new TaxBadWebhookPayloadError("No address found in taxBase"); } return payload; diff --git a/apps/taxes/src/pages/api/webhooks/order-calculate-taxes.ts b/apps/taxes/src/pages/api/webhooks/order-calculate-taxes.ts index 4090a3c..513eafd 100644 --- a/apps/taxes/src/pages/api/webhooks/order-calculate-taxes.ts +++ b/apps/taxes/src/pages/api/webhooks/order-calculate-taxes.ts @@ -7,6 +7,7 @@ import { saleorApp } from "../../../../saleor-app"; import { createLogger } from "../../../lib/logger"; import { getActiveConnectionService } from "../../../modules/taxes/get-active-connection-service"; import { WebhookResponse } from "../../../modules/app/webhook-response"; +import { TaxBadWebhookPayloadError } from "../../../modules/taxes/tax-error"; export const config = { api: { @@ -18,11 +19,11 @@ type CalculateTaxesPayload = Extract