openclaw-smart-fetch 0.3.4 → 0.3.5
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/dist/index.js +104 -34
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10085,42 +10085,54 @@ function buildUserFacingFetchErrorSummary(error) {
|
|
|
10085
10085
|
return "No readable content could be extracted from the page.";
|
|
10086
10086
|
case "processing_error":
|
|
10087
10087
|
return "The response could not be processed.";
|
|
10088
|
-
case "network_error":
|
|
10088
|
+
case "network_error": {
|
|
10089
|
+
if (/dns error/i.test(error.error)) {
|
|
10090
|
+
return "DNS error \u2014 could not resolve the hostname.";
|
|
10091
|
+
}
|
|
10092
|
+
if (/connection failed|connection refused|unreachable/i.test(error.error)) {
|
|
10093
|
+
return "Connection failed \u2014 the server is unreachable.";
|
|
10094
|
+
}
|
|
10095
|
+
if (/tls|ssl/i.test(error.error)) {
|
|
10096
|
+
return "TLS/SSL error \u2014 certificate may be invalid.";
|
|
10097
|
+
}
|
|
10089
10098
|
return "The request failed before a usable response was returned.";
|
|
10099
|
+
}
|
|
10090
10100
|
default:
|
|
10091
10101
|
return error.error;
|
|
10092
10102
|
}
|
|
10093
10103
|
}
|
|
10094
10104
|
function buildFetchErrorResponseText(error) {
|
|
10095
10105
|
const lines = [`Error: ${error.error}`];
|
|
10096
|
-
|
|
10097
|
-
[
|
|
10098
|
-
|
|
10099
|
-
|
|
10100
|
-
|
|
10101
|
-
|
|
10102
|
-
|
|
10103
|
-
|
|
10104
|
-
|
|
10105
|
-
|
|
10106
|
-
|
|
10107
|
-
|
|
10108
|
-
|
|
10109
|
-
|
|
10110
|
-
|
|
10111
|
-
|
|
10112
|
-
|
|
10113
|
-
|
|
10114
|
-
|
|
10115
|
-
|
|
10116
|
-
|
|
10117
|
-
|
|
10118
|
-
|
|
10119
|
-
|
|
10120
|
-
|
|
10121
|
-
|
|
10122
|
-
|
|
10123
|
-
|
|
10106
|
+
if (error.code === "timeout" || error.code === "http_error" || error.code === "download_error") {
|
|
10107
|
+
const metadata = buildHeader([
|
|
10108
|
+
["URL", error.url],
|
|
10109
|
+
["Final URL", error.finalUrl],
|
|
10110
|
+
["Phase", error.phase ? describeErrorPhase(error.phase) : void 0],
|
|
10111
|
+
[
|
|
10112
|
+
"Timeout",
|
|
10113
|
+
error.timeoutMs ? formatDurationMs(error.timeoutMs) : void 0
|
|
10114
|
+
],
|
|
10115
|
+
[
|
|
10116
|
+
"HTTP status",
|
|
10117
|
+
error.statusCode ? `${error.statusCode}${error.statusText ? ` ${error.statusText}` : ""}` : void 0
|
|
10118
|
+
],
|
|
10119
|
+
["Mime type", error.mimeType],
|
|
10120
|
+
[
|
|
10121
|
+
"Content-Length",
|
|
10122
|
+
error.contentLength !== void 0 ? `${error.contentLength} bytes (${formatByteCount(error.contentLength)})` : void 0
|
|
10123
|
+
],
|
|
10124
|
+
[
|
|
10125
|
+
"Downloaded before failure",
|
|
10126
|
+
error.downloadedBytes !== void 0 ? `${error.downloadedBytes} bytes (${formatByteCount(error.downloadedBytes)})` : void 0
|
|
10127
|
+
],
|
|
10128
|
+
[
|
|
10129
|
+
"Suggested timeoutMs",
|
|
10130
|
+
error.code === "timeout" ? suggestRetryTimeoutMs(error) : void 0
|
|
10131
|
+
]
|
|
10132
|
+
]);
|
|
10133
|
+
if (metadata) {
|
|
10134
|
+
lines.push("", metadata);
|
|
10135
|
+
}
|
|
10124
10136
|
}
|
|
10125
10137
|
if (error.code === "timeout") {
|
|
10126
10138
|
lines.push(
|
|
@@ -10654,6 +10666,31 @@ function isTimeoutError(error) {
|
|
|
10654
10666
|
const message = error instanceof Error ? error.message : String(error);
|
|
10655
10667
|
return /timed out|timeout|deadline exceeded|abort(?:ed)?/i.test(message);
|
|
10656
10668
|
}
|
|
10669
|
+
function isDnsError(error) {
|
|
10670
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
10671
|
+
return /dns error|failed to lookup address|nodename nor servname provided|name resolution failed/i.test(
|
|
10672
|
+
message
|
|
10673
|
+
);
|
|
10674
|
+
}
|
|
10675
|
+
function isConnectError(error) {
|
|
10676
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
10677
|
+
return /client error \(connect\)|connection refused|tcp connect error|connection reset|network unreachable|no route to host/i.test(
|
|
10678
|
+
message
|
|
10679
|
+
);
|
|
10680
|
+
}
|
|
10681
|
+
function isTlsError(error) {
|
|
10682
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
10683
|
+
return /ssl.*error|tls.*error|bad certificate|certificate.*invalid|unknown.*issuer/i.test(
|
|
10684
|
+
message
|
|
10685
|
+
);
|
|
10686
|
+
}
|
|
10687
|
+
function extractHostname(url) {
|
|
10688
|
+
try {
|
|
10689
|
+
return new URL(url).hostname;
|
|
10690
|
+
} catch {
|
|
10691
|
+
return url;
|
|
10692
|
+
}
|
|
10693
|
+
}
|
|
10657
10694
|
function buildTimeoutError(context) {
|
|
10658
10695
|
const targetUrl = context.finalUrl ?? context.url;
|
|
10659
10696
|
const timeoutLabel = `${context.timeoutMs}ms`;
|
|
@@ -10731,14 +10768,47 @@ function buildThrownFetchError(error, context) {
|
|
|
10731
10768
|
if (isTimeoutError(error)) {
|
|
10732
10769
|
return buildTimeoutError(context);
|
|
10733
10770
|
}
|
|
10771
|
+
const hostname = extractHostname(context.url);
|
|
10772
|
+
if (isDnsError(error)) {
|
|
10773
|
+
return {
|
|
10774
|
+
error: `DNS error: failed to lookup address for ${hostname}. Check the URL and try again.`,
|
|
10775
|
+
code: "network_error",
|
|
10776
|
+
phase: "connecting",
|
|
10777
|
+
retryable: false,
|
|
10778
|
+
url: context.url,
|
|
10779
|
+
finalUrl: context.finalUrl
|
|
10780
|
+
};
|
|
10781
|
+
}
|
|
10782
|
+
if (isConnectError(error)) {
|
|
10783
|
+
return {
|
|
10784
|
+
error: `Connection failed to ${hostname}. The server may be unreachable or blocking requests.`,
|
|
10785
|
+
code: "network_error",
|
|
10786
|
+
phase: "connecting",
|
|
10787
|
+
retryable: true,
|
|
10788
|
+
url: context.url,
|
|
10789
|
+
finalUrl: context.finalUrl
|
|
10790
|
+
};
|
|
10791
|
+
}
|
|
10792
|
+
if (isTlsError(error)) {
|
|
10793
|
+
return {
|
|
10794
|
+
error: `TLS/SSL error connecting to ${hostname}. The server's certificate may be invalid.`,
|
|
10795
|
+
code: "network_error",
|
|
10796
|
+
phase: "connecting",
|
|
10797
|
+
retryable: false,
|
|
10798
|
+
url: context.url,
|
|
10799
|
+
finalUrl: context.finalUrl
|
|
10800
|
+
};
|
|
10801
|
+
}
|
|
10802
|
+
const isConnectLevel = isDnsError(error) || isConnectError(error) || isTlsError(error);
|
|
10803
|
+
const effectivePhase = isConnectLevel ? "connecting" : context.phase;
|
|
10734
10804
|
const message = error instanceof Error ? error.message : String(error);
|
|
10735
10805
|
const targetUrl = context.finalUrl ?? context.url;
|
|
10736
|
-
const phaseDescription =
|
|
10806
|
+
const phaseDescription = effectivePhase === "loading" ? "downloading the response" : effectivePhase === "waiting" ? "waiting for the server response" : effectivePhase === "connecting" ? "connecting" : "fetching";
|
|
10737
10807
|
return {
|
|
10738
|
-
error:
|
|
10739
|
-
code:
|
|
10740
|
-
phase:
|
|
10741
|
-
retryable:
|
|
10808
|
+
error: effectivePhase === "processing" ? `Failed while processing the response from ${targetUrl}: ${message}` : `Request failed while ${phaseDescription} for ${targetUrl}: ${message}`,
|
|
10809
|
+
code: effectivePhase === "processing" ? "processing_error" : effectivePhase === "loading" && context.mimeType ? "download_error" : "network_error",
|
|
10810
|
+
phase: effectivePhase,
|
|
10811
|
+
retryable: effectivePhase !== "processing",
|
|
10742
10812
|
timeoutMs: context.timeoutMs,
|
|
10743
10813
|
url: context.url,
|
|
10744
10814
|
finalUrl: context.finalUrl,
|