rezo 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +1507 -0
- package/assets/icon.svg +37 -0
- package/assets/logo-dark.svg +47 -0
- package/assets/logo.svg +58 -0
- package/dist/adapters/curl.cjs +1034 -0
- package/dist/adapters/curl.js +1031 -0
- package/dist/adapters/entries/curl.cjs +4 -0
- package/dist/adapters/entries/curl.d.ts +2136 -0
- package/dist/adapters/entries/curl.js +2 -0
- package/dist/adapters/entries/fetch.cjs +2 -0
- package/dist/adapters/entries/fetch.d.ts +2127 -0
- package/dist/adapters/entries/fetch.js +1 -0
- package/dist/adapters/entries/http.cjs +2 -0
- package/dist/adapters/entries/http.d.ts +2126 -0
- package/dist/adapters/entries/http.js +1 -0
- package/dist/adapters/entries/http2.cjs +4 -0
- package/dist/adapters/entries/http2.d.ts +2136 -0
- package/dist/adapters/entries/http2.js +2 -0
- package/dist/adapters/entries/react-native.cjs +2 -0
- package/dist/adapters/entries/react-native.d.ts +2126 -0
- package/dist/adapters/entries/react-native.js +1 -0
- package/dist/adapters/entries/xhr.cjs +2 -0
- package/dist/adapters/entries/xhr.d.ts +2127 -0
- package/dist/adapters/entries/xhr.js +1 -0
- package/dist/adapters/fetch.cjs +740 -0
- package/dist/adapters/fetch.js +739 -0
- package/dist/adapters/http.cjs +1153 -0
- package/dist/adapters/http.js +1151 -0
- package/dist/adapters/http2.cjs +957 -0
- package/dist/adapters/http2.js +956 -0
- package/dist/adapters/index.cjs +6 -0
- package/dist/adapters/index.js +7 -0
- package/dist/adapters/picker.cjs +342 -0
- package/dist/adapters/picker.js +331 -0
- package/dist/adapters/react-native.cjs +545 -0
- package/dist/adapters/react-native.js +544 -0
- package/dist/adapters/xhr.cjs +622 -0
- package/dist/adapters/xhr.js +621 -0
- package/dist/cache/dns-cache.cjs +118 -0
- package/dist/cache/dns-cache.js +113 -0
- package/dist/cache/file-cacher.cjs +264 -0
- package/dist/cache/file-cacher.js +261 -0
- package/dist/cache/index.cjs +13 -0
- package/dist/cache/index.js +5 -0
- package/dist/cache/lru-cache.cjs +96 -0
- package/dist/cache/lru-cache.js +93 -0
- package/dist/cache/response-cache.cjs +314 -0
- package/dist/cache/response-cache.js +310 -0
- package/dist/cache/url-store.cjs +288 -0
- package/dist/cache/url-store.js +285 -0
- package/dist/core/hooks.cjs +133 -0
- package/dist/core/hooks.js +120 -0
- package/dist/core/rezo.cjs +464 -0
- package/dist/core/rezo.js +458 -0
- package/dist/crawler.d.ts +6255 -0
- package/dist/dom/index.cjs +1 -0
- package/dist/dom/index.d.ts +23 -0
- package/dist/dom/index.js +1 -0
- package/dist/entries/crawler.cjs +5 -0
- package/dist/entries/crawler.js +2 -0
- package/dist/errors/rezo-error.cjs +722 -0
- package/dist/errors/rezo-error.js +716 -0
- package/dist/index.cjs +34 -0
- package/dist/index.d.ts +3335 -0
- package/dist/index.js +26 -0
- package/dist/platform/browser.cjs +9 -0
- package/dist/platform/browser.d.ts +3203 -0
- package/dist/platform/browser.js +7 -0
- package/dist/platform/bun.cjs +9 -0
- package/dist/platform/bun.d.ts +3203 -0
- package/dist/platform/bun.js +7 -0
- package/dist/platform/deno.cjs +9 -0
- package/dist/platform/deno.d.ts +3203 -0
- package/dist/platform/deno.js +7 -0
- package/dist/platform/node.cjs +9 -0
- package/dist/platform/node.d.ts +3203 -0
- package/dist/platform/node.js +7 -0
- package/dist/platform/react-native.cjs +9 -0
- package/dist/platform/react-native.d.ts +3203 -0
- package/dist/platform/react-native.js +7 -0
- package/dist/platform/worker.cjs +9 -0
- package/dist/platform/worker.d.ts +3203 -0
- package/dist/platform/worker.js +7 -0
- package/dist/plugin/addon/decodo/index.cjs +1 -0
- package/dist/plugin/addon/decodo/index.js +1 -0
- package/dist/plugin/addon/decodo/options.cjs +1 -0
- package/dist/plugin/addon/decodo/options.js +1 -0
- package/dist/plugin/addon/oxylabs/index.cjs +1 -0
- package/dist/plugin/addon/oxylabs/index.js +1 -0
- package/dist/plugin/addon/oxylabs/options.cjs +1 -0
- package/dist/plugin/addon/oxylabs/options.js +1 -0
- package/dist/plugin/crawler-options.cjs +1 -0
- package/dist/plugin/crawler-options.js +1 -0
- package/dist/plugin/crawler.cjs +519 -0
- package/dist/plugin/crawler.js +517 -0
- package/dist/plugin/index.cjs +36 -0
- package/dist/plugin/index.js +32 -0
- package/dist/proxy/index.cjs +142 -0
- package/dist/proxy/index.js +139 -0
- package/dist/responses/buildError.cjs +452 -0
- package/dist/responses/buildError.js +441 -0
- package/dist/responses/buildResponse.cjs +365 -0
- package/dist/responses/buildResponse.js +361 -0
- package/dist/responses/download.cjs +54 -0
- package/dist/responses/download.js +52 -0
- package/dist/responses/stream.cjs +60 -0
- package/dist/responses/stream.js +58 -0
- package/dist/responses/upload.cjs +54 -0
- package/dist/responses/upload.js +52 -0
- package/dist/types/cookies.cjs +394 -0
- package/dist/types/cookies.js +391 -0
- package/dist/types/download.cjs +10 -0
- package/dist/types/download.js +10 -0
- package/dist/types/rezo-request.cjs +131 -0
- package/dist/types/rezo-request.js +131 -0
- package/dist/utils/agent-merger.cjs +111 -0
- package/dist/utils/agent-merger.js +108 -0
- package/dist/utils/compression.cjs +84 -0
- package/dist/utils/compression.js +82 -0
- package/dist/utils/cookies.cjs +514 -0
- package/dist/utils/cookies.js +511 -0
- package/dist/utils/data-operations.cjs +75 -0
- package/dist/utils/data-operations.js +73 -0
- package/dist/utils/form-data.cjs +164 -0
- package/dist/utils/form-data.js +161 -0
- package/dist/utils/headers.cjs +162 -0
- package/dist/utils/headers.js +161 -0
- package/dist/utils/http-config.cjs +723 -0
- package/dist/utils/http-config.js +718 -0
- package/dist/utils/index.cjs +8 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/tools.cjs +18 -0
- package/dist/utils/tools.js +15 -0
- package/package.json +172 -0
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
import { RezoError } from '../errors/rezo-error.js';
|
|
2
|
+
import { buildResponse } from './buildResponse.js';
|
|
3
|
+
function traverseCauseChain(error, detector, maxDepth = 10) {
|
|
4
|
+
let current = error;
|
|
5
|
+
let depth = 0;
|
|
6
|
+
while (current && depth < maxDepth) {
|
|
7
|
+
const result = detector(current);
|
|
8
|
+
if (result)
|
|
9
|
+
return result;
|
|
10
|
+
current = current.cause;
|
|
11
|
+
depth++;
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
function isSocksLikeError(error) {
|
|
16
|
+
const name = error.name || "";
|
|
17
|
+
const message = (error.message || "").toLowerCase();
|
|
18
|
+
const code = error.code || "";
|
|
19
|
+
if (name === "SocksClientError" || name.includes("Socks") || name.includes("SOCKS")) {
|
|
20
|
+
return detectSocksError(error.message);
|
|
21
|
+
}
|
|
22
|
+
if (message.includes("socks")) {
|
|
23
|
+
return detectSocksError(error.message);
|
|
24
|
+
}
|
|
25
|
+
if (message.includes("sockshost") || message.includes("socks proxy") || message.includes("socks5") || message.includes("socks4")) {
|
|
26
|
+
return detectSocksError(error.message);
|
|
27
|
+
}
|
|
28
|
+
if (error.options?.proxy?.type === 4 || error.options?.proxy?.type === 5) {
|
|
29
|
+
return detectSocksError(error.message);
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
function isProxyLikeError(error) {
|
|
34
|
+
const name = error.name || "";
|
|
35
|
+
const message = (error.message || "").toLowerCase();
|
|
36
|
+
const code = error.code || "";
|
|
37
|
+
if (name.includes("Proxy") || name.includes("proxy")) {
|
|
38
|
+
return detectProxyError(error.message, code);
|
|
39
|
+
}
|
|
40
|
+
if (message.includes("proxy") || message.includes("http proxy") || message.includes("https proxy")) {
|
|
41
|
+
return detectProxyError(error.message, code);
|
|
42
|
+
}
|
|
43
|
+
if (message.includes("connect tunnel") || message.includes("tunnel connection")) {
|
|
44
|
+
return detectProxyError(error.message, code);
|
|
45
|
+
}
|
|
46
|
+
if (message.includes("407")) {
|
|
47
|
+
return { type: "proxy", code: "REZ_PROXY_AUTHENTICATION_FAILED", message: error.message };
|
|
48
|
+
}
|
|
49
|
+
if (error.stack) {
|
|
50
|
+
const stack = error.stack.toLowerCase();
|
|
51
|
+
if (stack.includes("proxy-agent") || stack.includes("proxyagent")) {
|
|
52
|
+
if (code === "ECONNREFUSED" || code === "ECONNRESET") {
|
|
53
|
+
return { type: "proxy", code: "REZ_PROXY_CONNECTION_FAILED", message: error.message };
|
|
54
|
+
}
|
|
55
|
+
if (code === "ETIMEDOUT") {
|
|
56
|
+
return { type: "proxy", code: "REZ_PROXY_TIMEOUT", message: error.message };
|
|
57
|
+
}
|
|
58
|
+
return detectProxyError(error.message, code);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const errorAny = error;
|
|
62
|
+
if (errorAny.options?.proxy || errorAny.proxy || errorAny.proxyUrl) {
|
|
63
|
+
if (code === "ECONNREFUSED" || code === "ECONNRESET") {
|
|
64
|
+
return { type: "proxy", code: "REZ_PROXY_CONNECTION_FAILED", message: error.message };
|
|
65
|
+
}
|
|
66
|
+
if (code === "ETIMEDOUT") {
|
|
67
|
+
return { type: "proxy", code: "REZ_PROXY_TIMEOUT", message: error.message };
|
|
68
|
+
}
|
|
69
|
+
return detectProxyError(error.message, code);
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
function detectErrorType(error) {
|
|
74
|
+
const errorMessage = error.message || "";
|
|
75
|
+
const errorCode = error.code || "";
|
|
76
|
+
const socksResult = traverseCauseChain(error, isSocksLikeError);
|
|
77
|
+
if (socksResult)
|
|
78
|
+
return socksResult;
|
|
79
|
+
const proxyResult = traverseCauseChain(error, isProxyLikeError);
|
|
80
|
+
if (proxyResult)
|
|
81
|
+
return proxyResult;
|
|
82
|
+
if (isTlsError(errorCode, errorMessage)) {
|
|
83
|
+
return { type: "tls", code: mapTlsCode(errorCode, errorMessage), message: errorMessage };
|
|
84
|
+
}
|
|
85
|
+
if (isTimeoutError(errorCode, errorMessage)) {
|
|
86
|
+
return { type: "timeout", code: mapTimeoutCode(errorCode), message: errorMessage };
|
|
87
|
+
}
|
|
88
|
+
if (isAbortError(errorCode, errorMessage)) {
|
|
89
|
+
return { type: "abort", code: "ABORT_ERR", message: errorMessage };
|
|
90
|
+
}
|
|
91
|
+
if (isNetworkError(errorCode)) {
|
|
92
|
+
const msg = errorMessage.toLowerCase();
|
|
93
|
+
if (msg.includes("socks") || msg.includes("proxy")) {
|
|
94
|
+
if (msg.includes("socks")) {
|
|
95
|
+
return detectSocksError(errorMessage);
|
|
96
|
+
}
|
|
97
|
+
return detectProxyError(errorMessage, errorCode);
|
|
98
|
+
}
|
|
99
|
+
return { type: "network", code: errorCode, message: errorMessage };
|
|
100
|
+
}
|
|
101
|
+
return { type: "unknown", code: "REZ_UNKNOWN_ERROR", message: errorMessage };
|
|
102
|
+
}
|
|
103
|
+
function detectSocksError(message) {
|
|
104
|
+
const msg = message.toLowerCase();
|
|
105
|
+
if (msg.includes("authentication") || msg.includes("auth") || msg.includes("username") || msg.includes("password")) {
|
|
106
|
+
return { type: "socks", code: "REZ_SOCKS_AUTHENTICATION_FAILED", message };
|
|
107
|
+
}
|
|
108
|
+
if (msg.includes("connect") && (msg.includes("refused") || msg.includes("failed") || msg.includes("timeout"))) {
|
|
109
|
+
return { type: "socks", code: "REZ_SOCKS_CONNECTION_FAILED", message };
|
|
110
|
+
}
|
|
111
|
+
if (msg.includes("destination") || msg.includes("target") || msg.includes("host unreachable") || msg.includes("network unreachable")) {
|
|
112
|
+
return { type: "socks", code: "REZ_SOCKS_TARGET_CONNECTION_FAILED", message };
|
|
113
|
+
}
|
|
114
|
+
if (msg.includes("protocol") || msg.includes("version") || msg.includes("invalid") || msg.includes("malformed")) {
|
|
115
|
+
return { type: "socks", code: "REZ_SOCKS_PROTOCOL_ERROR", message };
|
|
116
|
+
}
|
|
117
|
+
if (msg.includes("internal") || msg.includes("should not happen")) {
|
|
118
|
+
return { type: "socks", code: "REZ_SOCKS_PROTOCOL_ERROR", message };
|
|
119
|
+
}
|
|
120
|
+
return { type: "socks", code: "REZ_SOCKS_CONNECTION_FAILED", message };
|
|
121
|
+
}
|
|
122
|
+
function detectProxyError(message, code) {
|
|
123
|
+
const msg = message.toLowerCase();
|
|
124
|
+
if (msg.includes("407") || msg.includes("authentication") || msg.includes("auth") || msg.includes("unauthorized")) {
|
|
125
|
+
return { type: "proxy", code: "REZ_PROXY_AUTHENTICATION_FAILED", message };
|
|
126
|
+
}
|
|
127
|
+
if (msg.includes("connect") && (msg.includes("refused") || msg.includes("failed"))) {
|
|
128
|
+
return { type: "proxy", code: "REZ_PROXY_CONNECTION_FAILED", message };
|
|
129
|
+
}
|
|
130
|
+
if (msg.includes("timeout") || code === "ETIMEDOUT") {
|
|
131
|
+
return { type: "proxy", code: "REZ_PROXY_TIMEOUT", message };
|
|
132
|
+
}
|
|
133
|
+
if (msg.includes("502") || msg.includes("504") || msg.includes("bad gateway") || msg.includes("unreachable")) {
|
|
134
|
+
return { type: "proxy", code: "REZ_PROXY_TARGET_UNREACHABLE", message };
|
|
135
|
+
}
|
|
136
|
+
return { type: "proxy", code: "REZ_PROXY_ERROR", message };
|
|
137
|
+
}
|
|
138
|
+
function isTlsError(code, message) {
|
|
139
|
+
const tlsCodes = [
|
|
140
|
+
"EPROTO",
|
|
141
|
+
"ERR_TLS_CERT_ALTNAME_INVALID",
|
|
142
|
+
"ERR_TLS_HANDSHAKE_TIMEOUT",
|
|
143
|
+
"ERR_TLS_INVALID_PROTOCOL_VERSION",
|
|
144
|
+
"CERT_HAS_EXPIRED",
|
|
145
|
+
"UNABLE_TO_VERIFY_LEAF_SIGNATURE",
|
|
146
|
+
"SELF_SIGNED_CERT_IN_CHAIN",
|
|
147
|
+
"DEPTH_ZERO_SELF_SIGNED_CERT",
|
|
148
|
+
"ERR_TLS_RENEGOTIATION_DISABLED",
|
|
149
|
+
"ERR_TLS_CERT_SIGNATURE_ALGORITHM_UNSUPPORTED"
|
|
150
|
+
];
|
|
151
|
+
if (tlsCodes.includes(code))
|
|
152
|
+
return true;
|
|
153
|
+
const msg = message.toLowerCase();
|
|
154
|
+
return msg.includes("certificate") || msg.includes("ssl") || msg.includes("tls") || msg.includes("handshake");
|
|
155
|
+
}
|
|
156
|
+
function mapTlsCode(code, message) {
|
|
157
|
+
if (code && code.startsWith("ERR_TLS") || code.startsWith("CERT_") || code === "EPROTO" || code.startsWith("UNABLE_TO") || code.startsWith("SELF_SIGNED") || code.startsWith("DEPTH_ZERO")) {
|
|
158
|
+
return code;
|
|
159
|
+
}
|
|
160
|
+
const msg = message.toLowerCase();
|
|
161
|
+
if (msg.includes("expired"))
|
|
162
|
+
return "CERT_HAS_EXPIRED";
|
|
163
|
+
if (msg.includes("self-signed") || msg.includes("self signed"))
|
|
164
|
+
return "SELF_SIGNED_CERT_IN_CHAIN";
|
|
165
|
+
if (msg.includes("hostname") || msg.includes("altname"))
|
|
166
|
+
return "ERR_TLS_CERT_ALTNAME_INVALID";
|
|
167
|
+
if (msg.includes("handshake") && msg.includes("timeout"))
|
|
168
|
+
return "ERR_TLS_HANDSHAKE_TIMEOUT";
|
|
169
|
+
return "EPROTO";
|
|
170
|
+
}
|
|
171
|
+
function isTimeoutError(code, message) {
|
|
172
|
+
const timeoutCodes = ["ETIMEDOUT", "UND_ERR_CONNECT_TIMEOUT", "UND_ERR_HEADERS_TIMEOUT", "UND_ERR_REQUEST_TIMEOUT", "ERR_TLS_HANDSHAKE_TIMEOUT"];
|
|
173
|
+
if (timeoutCodes.includes(code))
|
|
174
|
+
return true;
|
|
175
|
+
return message.toLowerCase().includes("timeout") && !message.toLowerCase().includes("proxy");
|
|
176
|
+
}
|
|
177
|
+
function mapTimeoutCode(code) {
|
|
178
|
+
if (code && code.includes("TIMEOUT"))
|
|
179
|
+
return code;
|
|
180
|
+
return "ETIMEDOUT";
|
|
181
|
+
}
|
|
182
|
+
function isAbortError(code, message) {
|
|
183
|
+
const abortCodes = ["ABORT_ERR", "UND_ERR_ABORTED", "ERR_ABORTED"];
|
|
184
|
+
if (abortCodes.includes(code))
|
|
185
|
+
return true;
|
|
186
|
+
return message.toLowerCase().includes("aborted");
|
|
187
|
+
}
|
|
188
|
+
function isNetworkError(code) {
|
|
189
|
+
const networkCodes = ["ECONNREFUSED", "ECONNRESET", "ENOTFOUND", "EAI_AGAIN", "EPIPE", "EHOSTUNREACH", "ENETUNREACH", "UND_ERR_SOCKET"];
|
|
190
|
+
return networkCodes.includes(code);
|
|
191
|
+
}
|
|
192
|
+
function shouldFilterStackLine(line) {
|
|
193
|
+
if (!line.trim().startsWith("at "))
|
|
194
|
+
return false;
|
|
195
|
+
if (line.includes("/node_modules/socks/"))
|
|
196
|
+
return true;
|
|
197
|
+
if (line.includes("/node_modules/socks-proxy-agent/"))
|
|
198
|
+
return true;
|
|
199
|
+
if (line.includes("/node_modules/http-proxy-agent/"))
|
|
200
|
+
return true;
|
|
201
|
+
if (line.includes("/node_modules/https-proxy-agent/"))
|
|
202
|
+
return true;
|
|
203
|
+
if (line.includes("/node_modules/agent-base/"))
|
|
204
|
+
return true;
|
|
205
|
+
if (line.includes("/src/adapters/"))
|
|
206
|
+
return true;
|
|
207
|
+
if (line.includes("/src/responses/"))
|
|
208
|
+
return true;
|
|
209
|
+
if (line.includes("/src/errors/"))
|
|
210
|
+
return true;
|
|
211
|
+
if (line.includes("/src/core/"))
|
|
212
|
+
return true;
|
|
213
|
+
if (line.includes("/src/utils/"))
|
|
214
|
+
return true;
|
|
215
|
+
if (line.includes("/src/proxy/"))
|
|
216
|
+
return true;
|
|
217
|
+
if (line.includes("node:internal/"))
|
|
218
|
+
return true;
|
|
219
|
+
if (line.includes("node:_http"))
|
|
220
|
+
return true;
|
|
221
|
+
if (line.includes("node:events"))
|
|
222
|
+
return true;
|
|
223
|
+
if (line.includes("node:net"))
|
|
224
|
+
return true;
|
|
225
|
+
if (line.includes("node:tls"))
|
|
226
|
+
return true;
|
|
227
|
+
if (line.includes("node:stream"))
|
|
228
|
+
return true;
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
function maskPathInLine(line) {
|
|
232
|
+
return line.replace(/\(\/[^)]+\/([^/)]+:[0-9]+:[0-9]+)\)/g, "($1)").replace(/at \/[^\s]+\/([^\s]+:[0-9]+:[0-9]+)/g, "at $1");
|
|
233
|
+
}
|
|
234
|
+
function cleanStackTrace(stack) {
|
|
235
|
+
if (!stack)
|
|
236
|
+
return;
|
|
237
|
+
const lines = stack.split(`
|
|
238
|
+
`);
|
|
239
|
+
const cleanedLines = [];
|
|
240
|
+
let userFrameCount = 0;
|
|
241
|
+
const maxUserFrames = 5;
|
|
242
|
+
for (const line of lines) {
|
|
243
|
+
if (!line.trim().startsWith("at ")) {
|
|
244
|
+
cleanedLines.push(line);
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (shouldFilterStackLine(line)) {
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (userFrameCount < maxUserFrames) {
|
|
251
|
+
cleanedLines.push(maskPathInLine(line));
|
|
252
|
+
userFrameCount++;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (cleanedLines.length === 0) {
|
|
256
|
+
return lines[0] || undefined;
|
|
257
|
+
}
|
|
258
|
+
return cleanedLines.join(`
|
|
259
|
+
`);
|
|
260
|
+
}
|
|
261
|
+
export function buildHttpError(params) {
|
|
262
|
+
const {
|
|
263
|
+
statusCode,
|
|
264
|
+
headers,
|
|
265
|
+
contentType,
|
|
266
|
+
contentLength,
|
|
267
|
+
cookies,
|
|
268
|
+
statusText,
|
|
269
|
+
url,
|
|
270
|
+
body,
|
|
271
|
+
finalUrl,
|
|
272
|
+
config,
|
|
273
|
+
request
|
|
274
|
+
} = params;
|
|
275
|
+
const response = buildResponse({
|
|
276
|
+
statusCode,
|
|
277
|
+
statusMessage: statusText,
|
|
278
|
+
headers,
|
|
279
|
+
body,
|
|
280
|
+
contentType,
|
|
281
|
+
contentLength,
|
|
282
|
+
cookies,
|
|
283
|
+
url,
|
|
284
|
+
finalUrl: finalUrl || url,
|
|
285
|
+
urls: [url],
|
|
286
|
+
config
|
|
287
|
+
});
|
|
288
|
+
return RezoError.createHttpError(statusCode, config, request, response);
|
|
289
|
+
}
|
|
290
|
+
export function buildDownloadError(messageOrParams, config, request, response) {
|
|
291
|
+
if (typeof messageOrParams === "string") {
|
|
292
|
+
return RezoError.createDownloadError(messageOrParams, config, request, response);
|
|
293
|
+
}
|
|
294
|
+
const { statusCode, headers, cookies, statusText, url, body, finalUrl, config: errorConfig, request: errorRequest } = messageOrParams;
|
|
295
|
+
const errorResponse = buildResponse({
|
|
296
|
+
statusCode,
|
|
297
|
+
statusMessage: statusText,
|
|
298
|
+
headers,
|
|
299
|
+
body,
|
|
300
|
+
contentType: headers["content-type"],
|
|
301
|
+
contentLength: headers["content-length"] || "0",
|
|
302
|
+
cookies,
|
|
303
|
+
url,
|
|
304
|
+
finalUrl: finalUrl || url,
|
|
305
|
+
urls: [url],
|
|
306
|
+
config: errorConfig
|
|
307
|
+
});
|
|
308
|
+
return RezoError.createDownloadError("Download failed", errorConfig, errorRequest, errorResponse);
|
|
309
|
+
}
|
|
310
|
+
export function buildDecompressionError(messageOrParams, config, request, response) {
|
|
311
|
+
if (typeof messageOrParams === "string") {
|
|
312
|
+
return RezoError.createDecompressionError(messageOrParams, config, request, response);
|
|
313
|
+
}
|
|
314
|
+
const { statusCode, headers, cookies, statusText, url, body, finalUrl, config: errorConfig, request: errorRequest } = messageOrParams;
|
|
315
|
+
const errorResponse = buildResponse({
|
|
316
|
+
statusCode,
|
|
317
|
+
statusMessage: statusText,
|
|
318
|
+
headers,
|
|
319
|
+
body,
|
|
320
|
+
contentType: headers["content-type"],
|
|
321
|
+
contentLength: headers["content-length"] || "0",
|
|
322
|
+
cookies,
|
|
323
|
+
url,
|
|
324
|
+
finalUrl: finalUrl || url,
|
|
325
|
+
urls: [url],
|
|
326
|
+
config: errorConfig
|
|
327
|
+
});
|
|
328
|
+
return RezoError.createDecompressionError("Decompression failed", errorConfig, errorRequest, errorResponse);
|
|
329
|
+
}
|
|
330
|
+
export function buildRedirectError(messageOrParams, config, request, response) {
|
|
331
|
+
if (typeof messageOrParams === "string") {
|
|
332
|
+
return RezoError.createRedirectError(messageOrParams, config, request, response);
|
|
333
|
+
}
|
|
334
|
+
const { statusCode, headers, cookies, statusText, url, body, finalUrl, config: errorConfig, request: errorRequest } = messageOrParams;
|
|
335
|
+
const errorResponse = buildResponse({
|
|
336
|
+
statusCode,
|
|
337
|
+
statusMessage: statusText,
|
|
338
|
+
headers,
|
|
339
|
+
body,
|
|
340
|
+
contentType: headers["content-type"],
|
|
341
|
+
contentLength: headers["content-length"] || "0",
|
|
342
|
+
cookies,
|
|
343
|
+
url,
|
|
344
|
+
finalUrl: finalUrl || url,
|
|
345
|
+
urls: [url],
|
|
346
|
+
config: errorConfig
|
|
347
|
+
});
|
|
348
|
+
return RezoError.createRedirectError("Redirect location not found", errorConfig, errorRequest, errorResponse);
|
|
349
|
+
}
|
|
350
|
+
export function builErrorFromResponse(message, response, config, request) {
|
|
351
|
+
return RezoError.createRedirectError(message, config, request, response);
|
|
352
|
+
}
|
|
353
|
+
export function buildNetworkError(message, code, config, request) {
|
|
354
|
+
return RezoError.createNetworkError(message, code, config, request);
|
|
355
|
+
}
|
|
356
|
+
export function buildTimeoutError(message, config, request) {
|
|
357
|
+
return RezoError.createTimeoutError(message, config, request);
|
|
358
|
+
}
|
|
359
|
+
export function buildAbortError(message, config, request) {
|
|
360
|
+
return RezoError.createAbortError(message, config, request);
|
|
361
|
+
}
|
|
362
|
+
function hasProxyConfigured(config) {
|
|
363
|
+
const proxy = config?.proxy;
|
|
364
|
+
if (!proxy)
|
|
365
|
+
return { isProxy: false, isSocks: false };
|
|
366
|
+
if (typeof proxy === "string") {
|
|
367
|
+
const lower = proxy.toLowerCase();
|
|
368
|
+
return {
|
|
369
|
+
isProxy: true,
|
|
370
|
+
isSocks: lower.startsWith("socks4://") || lower.startsWith("socks5://") || lower.startsWith("socks://")
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
if (typeof proxy === "object") {
|
|
374
|
+
const protocol = proxy.protocol?.toLowerCase() || "";
|
|
375
|
+
return {
|
|
376
|
+
isProxy: true,
|
|
377
|
+
isSocks: protocol.includes("socks")
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
return { isProxy: false, isSocks: false };
|
|
381
|
+
}
|
|
382
|
+
export function buildSmartError(config, request, cause) {
|
|
383
|
+
if (!cause) {
|
|
384
|
+
return new RezoError("Unknown error occurred", config, "REZ_UNKNOWN_ERROR", request);
|
|
385
|
+
}
|
|
386
|
+
let detected = detectErrorType(cause);
|
|
387
|
+
if (detected.type === "network" || detected.type === "unknown") {
|
|
388
|
+
const proxyConfig = hasProxyConfigured(config);
|
|
389
|
+
const errorCode = cause.code || "";
|
|
390
|
+
if (proxyConfig.isSocks) {
|
|
391
|
+
if (errorCode === "ECONNREFUSED" || errorCode === "ECONNRESET") {
|
|
392
|
+
detected = { type: "socks", code: "REZ_SOCKS_CONNECTION_FAILED", message: cause.message };
|
|
393
|
+
} else if (errorCode === "ETIMEDOUT") {
|
|
394
|
+
detected = { type: "socks", code: "REZ_SOCKS_CONNECTION_FAILED", message: cause.message };
|
|
395
|
+
} else if (errorCode === "EHOSTUNREACH" || errorCode === "ENETUNREACH") {
|
|
396
|
+
detected = { type: "socks", code: "REZ_SOCKS_TARGET_CONNECTION_FAILED", message: cause.message };
|
|
397
|
+
}
|
|
398
|
+
} else if (proxyConfig.isProxy) {
|
|
399
|
+
if (errorCode === "ECONNREFUSED" || errorCode === "ECONNRESET") {
|
|
400
|
+
detected = { type: "proxy", code: "REZ_PROXY_CONNECTION_FAILED", message: cause.message };
|
|
401
|
+
} else if (errorCode === "ETIMEDOUT") {
|
|
402
|
+
detected = { type: "proxy", code: "REZ_PROXY_TIMEOUT", message: cause.message };
|
|
403
|
+
} else if (errorCode === "EHOSTUNREACH" || errorCode === "ENETUNREACH") {
|
|
404
|
+
detected = { type: "proxy", code: "REZ_PROXY_TARGET_UNREACHABLE", message: cause.message };
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
let error;
|
|
409
|
+
switch (detected.type) {
|
|
410
|
+
case "socks":
|
|
411
|
+
error = RezoError.createSocksError(detected.code, config, request);
|
|
412
|
+
break;
|
|
413
|
+
case "proxy":
|
|
414
|
+
error = RezoError.createProxyError(detected.code, config, request);
|
|
415
|
+
break;
|
|
416
|
+
case "tls":
|
|
417
|
+
error = RezoError.createTlsError(detected.code, config, request);
|
|
418
|
+
break;
|
|
419
|
+
case "timeout":
|
|
420
|
+
error = RezoError.createTimeoutError(detected.message, config, request);
|
|
421
|
+
Object.defineProperty(error, "code", { value: detected.code, enumerable: true });
|
|
422
|
+
break;
|
|
423
|
+
case "abort":
|
|
424
|
+
error = RezoError.createAbortError(detected.message, config, request);
|
|
425
|
+
break;
|
|
426
|
+
case "network":
|
|
427
|
+
error = RezoError.createNetworkError(detected.message, detected.code, config, request);
|
|
428
|
+
break;
|
|
429
|
+
default:
|
|
430
|
+
error = new RezoError(detected.message || "Unknown error occurred", config, "REZ_UNKNOWN_ERROR", request);
|
|
431
|
+
}
|
|
432
|
+
Object.defineProperty(error, "cause", { value: cause, enumerable: false });
|
|
433
|
+
const cleanedStack = cleanStackTrace(error.stack);
|
|
434
|
+
if (cleanedStack) {
|
|
435
|
+
Object.defineProperty(error, "stack", { value: cleanedStack, enumerable: false });
|
|
436
|
+
}
|
|
437
|
+
return error;
|
|
438
|
+
}
|
|
439
|
+
export function buildGenericError(_message, config, request, cause) {
|
|
440
|
+
return buildSmartError(config, request, cause);
|
|
441
|
+
}
|