-
-
Notifications
You must be signed in to change notification settings - Fork 11.6k
Description
In v1.13.3, the refactoring of AxiosError to extend the native Error class (commit 1c6a86d) introduced a breaking change that makes the message property non-enumerable. This breaks existing code that relies on property enumeration methods.
The refactoring changed AxiosError from a constructor function pattern to an ES6 class extending Error.
While this is architecturally sound, it inadvertently changed the message property from enumerable to non-enumerable breaking standard JavaScript enumeration operations.
Reproduction:
const axios = require('axios');
// trigger an axios error
axios.get('https://httpbin.org/status/404')
.catch(err => {
console.log('Object.entries:', Object.entries(err));
// v1.13.2: message property is included
// v1.13.3: message property is MISSING
console.log('Object.keys:', Object.keys(err));
// v1.13.2: includes 'message'
// v1.13.3: does NOT include 'message'
console.log('Spread operator:', {...err});
// v1.13.2: includes message property
// v1.13.3: does NOT include message property
});
This affects any code that:
- Uses Object.entries(), Object.keys(), or Object.values() to enumerate error properties
- Spreads the error object: {...err}
- Serializes errors using for...in loops
- Logs or transmits error data using property enumeration
- Uses utility libraries that enumerate object properties for logging/monitoring
This change was released in a patch version (v1.13.2 -> v1.13.3), but it constitutes a breaking change according to https://semver.org/
Why was this breaking change shipped in a patch release rather than being deferred to v2.0.0? This violates the semver contract that patch versions are safe to upgrade without code changes.
One possible fix could be to make message explicitly enumerable to maintain backward compatibility:
constructor(message, code, config, request, response) {
super(message);
// Ensure backward compatibility by making message enumerable
Object.defineProperty(this, 'message', {
value: message,
enumerable: true,
writable: true,
configurable: true
});
this.name = 'AxiosError';
// ...
}
Best,
Alex