Skip to content

Commit

Permalink
feat: error handling for HttpErrorResponse
Browse files Browse the repository at this point in the history
  • Loading branch information
dianasavvatina committed Jan 14, 2025
1 parent 5085be1 commit d72b454
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
38 changes: 38 additions & 0 deletions packages/utils/src/ErrorContext.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { TezosOperationError, type TezosOperationErrorWithMessage } from "@taqui
import {
CustomError,
WalletConnectError,
explainHttpError,
explainTezError,
getErrorContext,
getWcErrorResponse,
Expand Down Expand Up @@ -61,6 +62,7 @@ describe("getErrorContext", () => {
expect(context.stacktrace).toBeDefined();
expect(context.timestamp).toBeDefined();
});

it("should handle WalletConnectError instances", () => {
const error = new WalletConnectError("Custom WC error message", "INTERNAL_ERROR", null);

Expand All @@ -71,6 +73,42 @@ describe("getErrorContext", () => {
expect(context.stacktrace).toBeDefined();
expect(context.timestamp).toBeDefined();
});

it("should handle HttpErrorResponse instances", () => {
const error = {
status: 503,
statusText: "",
message:
"Http error response: (503) <html><head><title>503 Service Temporarily Unavailable</title></head>",
url: "https://example.com/api",
};

const context = getErrorContext(error);
expect(context.description).toBe(
"HTTP request failed for https://example.com/api (503) Service Unavailable - The server is temporarily unable to handle the request. Please try again later or contact support."
);
expect(context.code).toBe(503);
expect(context.technicalDetails).toEqual([
503,
"Service Unavailable - The server is temporarily unable to handle the request. Please try again later or contact support.",
"",
"https://example.com/api",
]);
expect(context.stacktrace).toBeDefined();
expect(context.timestamp).toBeDefined();
});

it("should recognize well known http error codes", () => {
expect(explainHttpError(123)).toEqual(
"Unknown Error - Status code: 123. Please try again later or contact support."
);
for (const status of [400, 401, 403, 404, 405, 408, 409, 410, 500, 501, 502, 503, 504]) {
expect(explainHttpError(status)).toBeDefined();
expect(explainHttpError(status)).not.toEqual(
"Unknown Error - Status code: 123. Please try again later or contact support."
);
}
});
});

describe("explainTezError", () => {
Expand Down
35 changes: 35 additions & 0 deletions packages/utils/src/ErrorContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,30 @@ export const explainTezError = (err: string): string | undefined => {
}
};

export const explainHttpError = (status: number): string => {
const defaultAction = "Please try again later or contact support.";
const httpErrorDescriptions: { [key: number]: string } = {
400: "Bad Request - The server could not understand the request. Please check your input and try again.",
401: "Unauthorized - Authentication is required or has failed. Please log in and try again.",
403: "Forbidden - You do not have permission to access the requested resource. Contact support if you believe this is an error.",
404: `Not Found - The requested resource could not be found. ${defaultAction}`,
405: `Method Not Allowed - The HTTP method is not supported by the resource. ${defaultAction}`,
408: "Request Timeout - The server timed out waiting for the request. Please check your network connection and try again.",
409: `Conflict - There is a conflict with the current state of the resource. ${defaultAction}`,
410: `Gone - The resource is no longer available. It may have been removed or retired. ${defaultAction}`,
500: `Internal Server Error - An unexpected error occurred on the server. ${defaultAction}`,
501: "Not Implemented - The server does not support the functionality required to fulfill the request. Contact support for assistance.",
502: "Bad Gateway - The server received an invalid response from the upstream server. Please try again later.",
503: `Service Unavailable - The server is temporarily unable to handle the request. ${defaultAction}`,
504: "Gateway Timeout - The server did not receive a timely response from the upstream server. Check your network and try again.",
};

return (
httpErrorDescriptions[status] ||
`Unknown Error - Status code: ${status}. Please try again later or contact support.`
);
};

const isTezosOperationErrorWithMessage = (
error: TezosGenericOperationError
): error is TezosOperationErrorWithMessage => "with" in error;
Expand Down Expand Up @@ -119,6 +143,17 @@ export const getErrorContext = (error: any): ErrorContext => {
} else {
technicalDetails = [lastError.id];
}
} else if (
typeof error === "object" &&
"status" in error &&
"statusText" in error &&
"url" in error
) {
// HttpErrorResponse is defined in @angular. Too heavy for what we need.
const httpError = explainHttpError(error.status);
description = `HTTP request failed for ${error.url} (${error.status}) ${httpError}`;
code = error.status;
technicalDetails = [error.status, httpError, error.statusText, error.url];
} else if (error instanceof Error || Object.prototype.hasOwnProperty.call(error, "message")) {
const explanation = explainTezError(errorMessage);
if (explanation) {
Expand Down

1 comment on commit d72b454

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Title Lines Statements Branches Functions
apps/desktop Coverage: 83%
83.81% (1787/2132) 79.58% (850/1068) 78.27% (454/580)
apps/web Coverage: 83%
83.81% (1787/2132) 79.58% (850/1068) 78.27% (454/580)
packages/components Coverage: 97%
97.51% (196/201) 95.91% (94/98) 88.13% (52/59)
packages/core Coverage: 81%
82.37% (215/261) 72.51% (95/131) 81.66% (49/60)
packages/crypto Coverage: 100%
100% (43/43) 90.9% (10/11) 100% (7/7)
packages/data-polling Coverage: 97%
95.27% (141/148) 87.5% (21/24) 92.85% (39/42)
packages/multisig Coverage: 98%
98.47% (129/131) 85.71% (18/21) 100% (36/36)
packages/social-auth Coverage: 100%
100% (21/21) 100% (11/11) 100% (3/3)
packages/state Coverage: 85%
84.48% (828/980) 81.35% (192/236) 77.83% (302/388)
packages/tezos Coverage: 89%
88.72% (118/133) 94.59% (35/37) 86.84% (33/38)
packages/tzkt Coverage: 89%
87.32% (62/71) 87.5% (14/16) 80.48% (33/41)

Please sign in to comment.