Skip to content

Commit 227128d

Browse files
committed
feat: Add specific error types to request methods
- Added ConnectionRefusedError handling for ECONNREFUSED errors. - Added RequestTimeoutError handling for UND_ERR_CONNECT_TIMEOUT, UND_ERR_HEADERS_TIMEOUT, and UND_ERR_BODY_TIMEOUT errors.
1 parent 90eb189 commit 227128d

File tree

2 files changed

+84
-8
lines changed

2 files changed

+84
-8
lines changed

v-next/hardhat-utils/src/errors/request.ts

+12
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,15 @@ export class DispatcherError extends CustomError {
2020
super(`Failed to create dispatcher: ${message}`, cause);
2121
}
2222
}
23+
24+
export class RequestTimeoutError extends CustomError {
25+
constructor(url: string, cause?: Error) {
26+
super(`Request to ${sanitizeUrl(url)} timed out`, cause);
27+
}
28+
}
29+
30+
export class ConnectionRefusedError extends CustomError {
31+
constructor(url: string, cause?: Error) {
32+
super(`Connection to ${sanitizeUrl(url)} was refused`, cause);
33+
}
34+
}

v-next/hardhat-utils/src/request.ts

+72-8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {
1111
DownloadError,
1212
RequestError,
1313
DispatcherError,
14+
RequestTimeoutError,
15+
ConnectionRefusedError,
1416
} from "./errors/request.js";
1517
import { move } from "./fs.js";
1618
import {
@@ -66,7 +68,9 @@ export interface RequestOptions {
6668
* @param requestOptions The options to configure the request. See {@link RequestOptions}.
6769
* @param dispatcherOrDispatcherOptions Either a dispatcher or dispatcher options. See {@link DispatcherOptions}.
6870
* @returns The response data object. See {@link https://undici.nodejs.org/#/docs/api/Dispatcher?id=parameter-responsedata}.
69-
* @throws RequestError If the request fails.
71+
* @throws ConnectionRefusedError If the connection is refused by the server.
72+
* @throws RequestTimeoutError If the request times out.
73+
* @throws RequestError If the request fails for any other reason.
7074
*/
7175
export async function getRequest(
7276
url: string,
@@ -86,7 +90,20 @@ export async function getRequest(
8690
...baseRequestOptions,
8791
});
8892
} catch (e) {
89-
ensureError(e);
93+
ensureError<NodeJS.ErrnoException>(e);
94+
95+
if (e.code === "ECONNREFUSED") {
96+
throw new ConnectionRefusedError(url, e);
97+
}
98+
99+
if (
100+
e.code === "UND_ERR_CONNECT_TIMEOUT" ||
101+
e.code === "UND_ERR_HEADERS_TIMEOUT" ||
102+
e.code === "UND_ERR_BODY_TIMEOUT"
103+
) {
104+
throw new RequestTimeoutError(url, e);
105+
}
106+
90107
throw new RequestError(url, "GET", e);
91108
}
92109
}
@@ -99,7 +116,9 @@ export async function getRequest(
99116
* @param requestOptions The options to configure the request. See {@link RequestOptions}.
100117
* @param dispatcherOrDispatcherOptions Either a dispatcher or dispatcher options. See {@link DispatcherOptions}.
101118
* @returns The response data object. See {@link https://undici.nodejs.org/#/docs/api/Dispatcher?id=parameter-responsedata}.
102-
* @throws RequestError If the request fails.
119+
* @throws ConnectionRefusedError If the connection is refused by the server.
120+
* @throws RequestTimeoutError If the request times out.
121+
* @throws RequestError If the request fails for any other reason.
103122
*/
104123
export async function postJsonRequest(
105124
url: string,
@@ -125,7 +144,20 @@ export async function postJsonRequest(
125144
body: JSON.stringify(body),
126145
});
127146
} catch (e) {
128-
ensureError(e);
147+
ensureError<NodeJS.ErrnoException>(e);
148+
149+
if (e.code === "ECONNREFUSED") {
150+
throw new ConnectionRefusedError(url, e);
151+
}
152+
153+
if (
154+
e.code === "UND_ERR_CONNECT_TIMEOUT" ||
155+
e.code === "UND_ERR_HEADERS_TIMEOUT" ||
156+
e.code === "UND_ERR_BODY_TIMEOUT"
157+
) {
158+
throw new RequestTimeoutError(url, e);
159+
}
160+
129161
throw new RequestError(url, "POST", e);
130162
}
131163
}
@@ -138,7 +170,9 @@ export async function postJsonRequest(
138170
* @param requestOptions The options to configure the request. See {@link RequestOptions}.
139171
* @param dispatcherOrDispatcherOptions Either a dispatcher or dispatcher options. See {@link DispatcherOptions}.
140172
* @returns The response data object. See {@link https://undici.nodejs.org/#/docs/api/Dispatcher?id=parameter-responsedata}.
141-
* @throws RequestError If the request fails.
173+
* @throws ConnectionRefusedError If the connection is refused by the server.
174+
* @throws RequestTimeoutError If the request times out.
175+
* @throws RequestError If the request fails for any other reason.
142176
*/
143177
export async function postFormRequest(
144178
url: string,
@@ -165,7 +199,20 @@ export async function postFormRequest(
165199
body: querystring.stringify(body as ParsedUrlQueryInput),
166200
});
167201
} catch (e) {
168-
ensureError(e);
202+
ensureError<NodeJS.ErrnoException>(e);
203+
204+
if (e.code === "ECONNREFUSED") {
205+
throw new ConnectionRefusedError(url, e);
206+
}
207+
208+
if (
209+
e.code === "UND_ERR_CONNECT_TIMEOUT" ||
210+
e.code === "UND_ERR_HEADERS_TIMEOUT" ||
211+
e.code === "UND_ERR_BODY_TIMEOUT"
212+
) {
213+
throw new RequestTimeoutError(url, e);
214+
}
215+
169216
throw new RequestError(url, "POST", e);
170217
}
171218
}
@@ -177,7 +224,9 @@ export async function postFormRequest(
177224
* @param destination The absolute path to save the file to.
178225
* @param requestOptions The options to configure the request. See {@link RequestOptions}.
179226
* @param dispatcherOrDispatcherOptions Either a dispatcher or dispatcher options. See {@link DispatcherOptions}.
180-
* @throws DownloadFailedError If the download fails.
227+
* @throws ConnectionRefusedError If the connection is refused by the server.
228+
* @throws RequestTimeoutError If the request times out.
229+
* @throws DownloadFailedError If the download fails for any other reason.
181230
*/
182231
export async function download(
183232
url: string,
@@ -205,7 +254,20 @@ export async function download(
205254
await stream.pipeline(body, fileStream);
206255
await move(tempFilePath, destination);
207256
} catch (e) {
208-
ensureError(e);
257+
ensureError<NodeJS.ErrnoException>(e);
258+
259+
if (e.code === "ECONNREFUSED") {
260+
throw new ConnectionRefusedError(url, e);
261+
}
262+
263+
if (
264+
e.code === "UND_ERR_CONNECT_TIMEOUT" ||
265+
e.code === "UND_ERR_HEADERS_TIMEOUT" ||
266+
e.code === "UND_ERR_BODY_TIMEOUT"
267+
) {
268+
throw new RequestTimeoutError(url, e);
269+
}
270+
209271
throw new DownloadError(url, e);
210272
}
211273
}
@@ -301,4 +363,6 @@ export {
301363
DownloadError,
302364
RequestError,
303365
DispatcherError,
366+
RequestTimeoutError,
367+
ConnectionRefusedError,
304368
} from "./errors/request.js";

0 commit comments

Comments
 (0)