Skip to content

Commit bff0cb1

Browse files
refactor: simplify error handling in axios logger by consolidating error message formatting
1 parent 1b96cca commit bff0cb1

File tree

1 file changed

+41
-120
lines changed

1 file changed

+41
-120
lines changed

src/lib/axios-logger.ts

Lines changed: 41 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -14,131 +14,52 @@ const hasErrorProperty = <T extends keyof AxiosErrorObject>(
1414
return (obj as AxiosErrorObject)?.[propertyName] !== undefined;
1515
};
1616

17-
/**
18-
* Formats a single error field into a readable string
19-
*/
20-
function formatErrorField([key, value]: [string, any]): string {
21-
return Array.isArray(value)
22-
? `${key}: ${value.join(", ")}`
23-
: `${key}: ${value}`;
24-
}
25-
26-
/**
27-
* Formats validation errors for a single item (e.g., contact import error)
28-
*/
29-
function formatValidationItem(item: any): string {
30-
const parts = [];
31-
if (item.email) parts.push(`Email: ${item.email}`);
32-
33-
if (item.errors) {
34-
const errorParts = Object.entries(item.errors).map(formatErrorField);
35-
if (errorParts.length > 0) {
36-
parts.push(`Errors: ${errorParts.join("; ")}`);
37-
}
38-
}
39-
40-
return parts.join(" - ");
41-
}
42-
43-
/**
44-
* Formats an array of validation errors
45-
*/
46-
function formatValidationErrors(errors: any[]): string {
47-
return errors
48-
.map((item) =>
49-
typeof item === "object" && item !== null
50-
? formatValidationItem(item)
51-
: String(item)
52-
)
53-
.join(" | ");
54-
}
55-
56-
/**
57-
* Formats error messages from API response data
58-
*/
59-
function formatErrorMessage(data: any): string {
60-
if (!data || typeof data !== "object") {
61-
return String(data);
62-
}
63-
64-
// Handle array of errors
65-
if (Array.isArray(data)) {
66-
return formatValidationErrors(data);
67-
}
68-
69-
// Handle errors object with array of validation errors
70-
if (data.errors && Array.isArray(data.errors)) {
71-
return formatValidationErrors(data.errors);
72-
}
73-
74-
// Handle errors object with name/base arrays
75-
if (data.errors && !Array.isArray(data.errors)) {
76-
const errorParts = [];
77-
if (
78-
hasErrorProperty(data.errors, "name") &&
79-
Array.isArray(data.errors.name)
80-
) {
81-
errorParts.push(`Name errors: ${data.errors.name.join(", ")}`);
82-
}
83-
if (
84-
hasErrorProperty(data.errors, "base") &&
85-
Array.isArray(data.errors.base)
86-
) {
87-
errorParts.push(`Base errors: ${data.errors.base.join(", ")}`);
88-
}
89-
if (errorParts.length > 0) {
90-
return errorParts.join("; ");
91-
}
92-
}
93-
94-
// Handle simple error message
95-
if (data.error) {
96-
return String(data.error);
97-
}
98-
99-
// Handle message field
100-
if (data.message) {
101-
return String(data.message);
102-
}
103-
104-
// Fallback to JSON string for complex objects
105-
try {
106-
return JSON.stringify(data, null, 2);
107-
} catch {
108-
return String(data);
109-
}
110-
}
111-
11217
/**
11318
* Error handler for axios response.
11419
*/
11520
export default function handleSendingError(error: AxiosError | unknown) {
11621
if (axios.isAxiosError(error)) {
117-
const status = error.response?.status;
118-
const statusText = error.response?.statusText;
119-
const data = error.response?.data;
120-
121-
let message = `Request failed with status ${status}`;
122-
123-
// Add status text if available
124-
if (statusText) {
125-
message += ` (${statusText})`;
126-
}
127-
128-
// Add API error details if available
129-
if (data) {
130-
const formattedError = formatErrorMessage(data);
131-
if (formattedError) {
132-
message += `: ${formattedError}`;
133-
}
134-
}
135-
136-
// Add URL for context
137-
if (error.config?.url) {
138-
message += ` | URL: ${error.config.method?.toUpperCase()} ${
139-
error.config.url
140-
}`;
141-
}
22+
/**
23+
* Handles case where error is in `data.errors`.
24+
*/
25+
const serverErrorsObject =
26+
error.response?.data &&
27+
typeof error.response.data === "object" &&
28+
"errors" in error.response.data &&
29+
error.response.data.errors;
30+
31+
/**
32+
* Handles case where error is in `data.error`.
33+
*/
34+
const serverErrorObject =
35+
error.response?.data &&
36+
typeof error.response.data === "object" &&
37+
"error" in error.response.data &&
38+
error.response.data.error;
39+
40+
/**
41+
* Joins error messages contained in `name` property.
42+
*/
43+
const errorNames =
44+
hasErrorProperty(serverErrorsObject, "name") &&
45+
serverErrorsObject.name.join(", ");
46+
47+
/**
48+
* Joins error messages contained in `base` property.
49+
*/
50+
const errorBase =
51+
hasErrorProperty(serverErrorsObject, "base") &&
52+
serverErrorsObject.base.join(", ");
53+
54+
/**
55+
* Selects available error.
56+
*/
57+
const message =
58+
errorNames ||
59+
errorBase ||
60+
serverErrorsObject ||
61+
serverErrorObject ||
62+
error.message;
14263

14364
// @ts-expect-error weird typing around Error class, but it's tested to work
14465
throw new MailtrapError(message, { cause: error });

0 commit comments

Comments
 (0)