mirror of
https://github.com/tenrok/axios.git
synced 2026-06-17 19:21:29 +03:00
feat(adapter): surface low‑level network error details; attach original error via cause (#6982)
* feat(adapter): surface low‑level network error details; attach original error via `cause` Node http adapter: - Promote low-level `err.code` to `AxiosError.code`, prefixing message (e.g. `ECONNREFUSED – …`) - Keep original error on standard `Error.cause` XHR adapter: - Preserve browser `ProgressEvent` on `error.event` - Use event message when available Tests: - Add Node ESM tests under `test/unit/adapters` to assert `code` and `cause` behavior Types: - Ensure `AxiosError.cause?: unknown` and `event?: ProgressEvent` are present * fix(adapter): use fs instead of fs/promises for sync file read in tests to fix GitHub Actions
This commit is contained in:
+11
-8
@@ -104,15 +104,18 @@ export default isXHRAdapterSupported && function (config) {
|
||||
};
|
||||
|
||||
// Handle low level network errors
|
||||
request.onerror = function handleError() {
|
||||
// Real errors are hidden from us by the browser
|
||||
// onerror should only fire if it's a network error
|
||||
reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request));
|
||||
|
||||
// Clean up request
|
||||
request = null;
|
||||
request.onerror = function handleError(event) {
|
||||
// Browsers deliver a ProgressEvent in XHR onerror
|
||||
// (message may be empty; when present, surface it)
|
||||
// See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event
|
||||
const msg = event && event.message ? event.message : 'Network Error';
|
||||
const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);
|
||||
// attach the underlying event for consumers who want details
|
||||
err.event = event || null;
|
||||
reject(err);
|
||||
request = null;
|
||||
};
|
||||
|
||||
|
||||
// Handle timeout
|
||||
request.ontimeout = function handleTimeout() {
|
||||
let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';
|
||||
|
||||
+10
-3
@@ -89,11 +89,18 @@ AxiosError.from = (error, code, config, request, response, customProps) => {
|
||||
return prop !== 'isAxiosError';
|
||||
});
|
||||
|
||||
AxiosError.call(axiosError, error.message, code, config, request, response);
|
||||
const msg = error && error.message ? error.message : 'Error';
|
||||
|
||||
axiosError.cause = error;
|
||||
// Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED)
|
||||
const errCode = code == null && error ? error.code : code;
|
||||
AxiosError.call(axiosError, msg, errCode, config, request, response);
|
||||
|
||||
axiosError.name = error.name;
|
||||
// Chain the original error on the standard field; non-enumerable to avoid JSON noise
|
||||
if (error && axiosError.cause == null) {
|
||||
Object.defineProperty(axiosError, 'cause', { value: error, configurable: true });
|
||||
}
|
||||
|
||||
axiosError.name = (error && error.name) || 'Error';
|
||||
|
||||
customProps && Object.assign(axiosError, customProps);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user