refactor: ♻️ change error types
This commit is contained in:
parent
ce7b5cc5e1
commit
24c31d733a
5 changed files with 41 additions and 52 deletions
|
@ -1,41 +1,7 @@
|
||||||
import { NextApiResponse } from "next";
|
import { NextApiResponse } from "next";
|
||||||
|
|
||||||
import { AvalaraError } from "avatax/lib/AvaTaxClient";
|
|
||||||
import { ZodError } from "zod";
|
|
||||||
import { createLogger, Logger } from "../../lib/logger";
|
import { createLogger, Logger } from "../../lib/logger";
|
||||||
|
import { TaxBadWebhookPayloadError, TaxCriticalError } from "../taxes/tax-error";
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class WebhookResponse {
|
export class WebhookResponse {
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
|
@ -43,15 +9,30 @@ export class WebhookResponse {
|
||||||
this.logger = createLogger({ event: "WebhookResponse" });
|
this.logger = createLogger({ event: "WebhookResponse" });
|
||||||
}
|
}
|
||||||
|
|
||||||
error(error: unknown) {
|
private respondWithBadRequest(errorMessage: string) {
|
||||||
const errorResolver = new WebhookErrorResolver();
|
// Are we sure its 400?
|
||||||
const errorMessage = errorResolver.resolve(error);
|
return this.res.status(400).json({ error: errorMessage });
|
||||||
|
}
|
||||||
this.logger.debug({ errorMessage }, "Responding to Saleor with error:");
|
|
||||||
|
|
||||||
|
private respondWithInternalServerError(errorMessage: string) {
|
||||||
return this.res.status(500).json({ error: errorMessage });
|
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) {
|
success(data?: unknown) {
|
||||||
return this.res.status(200).json(data ?? {});
|
return this.res.status(200).json(data ?? {});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { DocumentType } from "avatax/lib/enums/DocumentType";
|
import { DocumentType } from "avatax/lib/enums/DocumentType";
|
||||||
import { CalculateTaxesPayload } from "../../../pages/api/webhooks/checkout-calculate-taxes";
|
import { CalculateTaxesPayload } from "../../../pages/api/webhooks/checkout-calculate-taxes";
|
||||||
import { discountUtils } from "../../taxes/discount-utils";
|
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 { taxProviderUtils } from "../../taxes/tax-provider-utils";
|
||||||
import { avataxAddressFactory } from "../address-factory";
|
import { avataxAddressFactory } from "../address-factory";
|
||||||
import { AvataxClient, CreateTransactionArgs } from "../avatax-client";
|
import { AvataxClient, CreateTransactionArgs } from "../avatax-client";
|
||||||
|
@ -31,7 +31,7 @@ export class AvataxCalculateTaxesPayloadTransformer {
|
||||||
return taxProviderUtils.resolveStringOrThrow(payload.taxBase.sourceObject.userEmail);
|
return taxProviderUtils.resolveStringOrThrow(payload.taxBase.sourceObject.userEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new TaxUnknownError("Cannot resolve customer code");
|
throw new TaxUnexpectedError("Cannot resolve customer code");
|
||||||
}
|
}
|
||||||
|
|
||||||
async transform(
|
async transform(
|
||||||
|
|
|
@ -2,11 +2,17 @@ import { BaseError } from "../../error";
|
||||||
|
|
||||||
const TaxError = BaseError.subclass("TaxError");
|
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
|
// Breaks the process. Is reported.
|
||||||
export const TaxKnownError = TaxError.subclass("TaxKnownError");
|
export const TaxCriticalError = TaxError.subclass("TaxCriticalError");
|
||||||
|
|
||||||
// An error that we throw but it shouldn't happen
|
// Error that shouldn't happen. Should provide extra insights for debugging.
|
||||||
export const TaxUnexpectedError = TaxError.subclass("TaxUnexpectedError");
|
export const TaxUnexpectedError = TaxCriticalError.subclass("TaxUnexpectedError");
|
||||||
|
|
||||||
|
// Error that happens when external service returns an error
|
||||||
|
export const TaxExternalError = TaxCriticalError.subclass("TaxExternalError");
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { saleorApp } from "../../../../saleor-app";
|
||||||
import { createLogger } from "../../../lib/logger";
|
import { createLogger } from "../../../lib/logger";
|
||||||
import { WebhookResponse } from "../../../modules/app/webhook-response";
|
import { WebhookResponse } from "../../../modules/app/webhook-response";
|
||||||
import { getActiveConnectionService } from "../../../modules/taxes/get-active-connection-service";
|
import { getActiveConnectionService } from "../../../modules/taxes/get-active-connection-service";
|
||||||
|
import { TaxBadWebhookPayloadError } from "../../../modules/taxes/tax-error";
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
api: {
|
api: {
|
||||||
|
@ -21,11 +22,11 @@ export type CalculateTaxesPayload = Extract<
|
||||||
|
|
||||||
function verifyCalculateTaxesPayload(payload: CalculateTaxesPayload) {
|
function verifyCalculateTaxesPayload(payload: CalculateTaxesPayload) {
|
||||||
if (!payload.taxBase.lines.length) {
|
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) {
|
if (!payload.taxBase.address) {
|
||||||
throw new Error("No address found in taxBase");
|
throw new TaxBadWebhookPayloadError("No address found in taxBase");
|
||||||
}
|
}
|
||||||
|
|
||||||
return payload;
|
return payload;
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { saleorApp } from "../../../../saleor-app";
|
||||||
import { createLogger } from "../../../lib/logger";
|
import { createLogger } from "../../../lib/logger";
|
||||||
import { getActiveConnectionService } from "../../../modules/taxes/get-active-connection-service";
|
import { getActiveConnectionService } from "../../../modules/taxes/get-active-connection-service";
|
||||||
import { WebhookResponse } from "../../../modules/app/webhook-response";
|
import { WebhookResponse } from "../../../modules/app/webhook-response";
|
||||||
|
import { TaxBadWebhookPayloadError } from "../../../modules/taxes/tax-error";
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
api: {
|
api: {
|
||||||
|
@ -18,11 +19,11 @@ type CalculateTaxesPayload = Extract<CalculateTaxesEventFragment, { __typename:
|
||||||
|
|
||||||
function verifyCalculateTaxesPayload(payload: CalculateTaxesPayload) {
|
function verifyCalculateTaxesPayload(payload: CalculateTaxesPayload) {
|
||||||
if (!payload.taxBase.lines.length) {
|
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) {
|
if (!payload.taxBase.address) {
|
||||||
throw new Error("No address found in taxBase");
|
throw new TaxBadWebhookPayloadError("No address found in taxBase");
|
||||||
}
|
}
|
||||||
|
|
||||||
return payload;
|
return payload;
|
||||||
|
|
Loading…
Reference in a new issue