-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy patherrors.ts
More file actions
139 lines (120 loc) · 3.75 KB
/
errors.ts
File metadata and controls
139 lines (120 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import { USER_AGENT } from '../consts';
/**
* Base exception for StackOne errors
*/
export class StackOneError extends Error {
constructor(message: string, options?: ErrorOptions) {
super(message, options);
this.name = 'StackOneError';
}
}
/**
* Raised when the StackOne API returns an error
*/
export class StackOneAPIError extends StackOneError {
statusCode: number;
responseBody: unknown;
providerErrors?: unknown[];
requestBody?: unknown;
constructor(
message: string,
statusCode: number,
responseBody: unknown,
requestBody?: unknown,
options?: ErrorOptions,
) {
// Extract the error message from responseBody if it exists
let errorMessage = message;
if (
responseBody &&
typeof responseBody === 'object' &&
'message' in responseBody &&
responseBody.message &&
typeof responseBody.message === 'string'
) {
errorMessage = `${message}: ${responseBody.message}`;
}
super(errorMessage, options);
this.name = 'StackOneAPIError';
this.statusCode = statusCode;
this.responseBody = responseBody;
this.requestBody = requestBody;
// Extract provider errors if they exist
if (
responseBody &&
typeof responseBody === 'object' &&
'provider_errors' in responseBody &&
Array.isArray(responseBody.provider_errors)
) {
this.providerErrors = responseBody.provider_errors;
}
}
toString(): string {
return this._formatErrorMessage();
}
// Format the error message for better readability
private _formatErrorMessage(): string {
// Format the main error message
let errorMessage = `API Error: ${this.statusCode} - ${this.message.replace(` for ${this._getUrlFromMessage()}`, '')}`;
// Add the URL on a new line for better readability
const url = this._getUrlFromMessage();
if (url) {
errorMessage += `\nEndpoint: ${url}`;
}
// Add request headers information (for debugging)
errorMessage += '\n\nRequest Headers:';
errorMessage += '\n- Authorization: [REDACTED]';
errorMessage += `\n- User-Agent: ${USER_AGENT}`;
// Add request body information if available
if (this.requestBody) {
errorMessage += '\n\nRequest Body:';
try {
if (typeof this.requestBody === 'object') {
errorMessage += `\n${JSON.stringify(this.requestBody, null, 2)}`;
} else if (typeof this.requestBody === 'string') {
errorMessage += ` ${this.requestBody}`;
} else {
errorMessage += ` ${JSON.stringify(this.requestBody)}`;
}
} catch {
errorMessage += ' [Unable to stringify request body]';
}
}
// Add provider error information if available
if (this.providerErrors && this.providerErrors.length > 0) {
errorMessage += this._formatProviderErrors();
}
return errorMessage;
}
// Format provider errors
private _formatProviderErrors(): string {
let errorMessage = '';
const providerError = this.providerErrors?.[0];
if (typeof providerError === 'object' && providerError !== null) {
errorMessage += '\n\nProvider Error:';
if ('status' in providerError && typeof providerError.status === 'number') {
errorMessage += ` ${providerError.status}`;
}
// Include raw error message if available
if (
'raw' in providerError &&
typeof providerError.raw === 'object' &&
providerError.raw !== null &&
'error' in providerError.raw &&
typeof providerError.raw.error === 'string'
) {
errorMessage += ` - ${providerError.raw.error}`;
}
// Add provider URL on a new line
if ('url' in providerError && typeof providerError.url === 'string') {
errorMessage += `\nProvider Endpoint: ${providerError.url}`;
}
}
return errorMessage;
}
// Helper method to extract URL from the error message
private _getUrlFromMessage(): string | null {
const match = this.message.match(/ for (https?:\/\/[^\s:]+)/);
return match ? match[1] : null;
}
}