fix: make AxiosError.message property enumerable (#7392)

* fix: make AxiosError.message property enumerable

Restores backward compatibility by making the message property
enumerable. In v1.13.3, the refactoring to extend native Error
made message non-enumerable, breaking code that uses Object.keys(),
Object.entries(), or spread operator on AxiosError instances.

This fix uses Object.defineProperty to explicitly make the message
property enumerable while maintaining the benefits of extending
the native Error class.

Breaking change introduced in: v1.13.3 (commit 1c6a86d)
Affects: Object.keys(), Object.entries(), spread operator, for...in loops

* chore: build fix

---------

Co-authored-by: Alexander Gehres <alexander.gehres@sap.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
This commit is contained in:
Alexander Gehres 2026-02-14 16:31:52 +01:00 committed by GitHub
parent ef3711d1b3
commit 822e3e40b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 55 additions and 22 deletions

View File

@ -11,29 +11,40 @@ class AxiosError extends Error {
return axiosError;
}
/**
* Create an Error with the specified message, config, error code, request and response.
*
* @param {string} message The error message.
* @param {string} [code] The error code (for example, 'ECONNABORTED').
* @param {Object} [config] The config.
* @param {Object} [request] The request.
* @param {Object} [response] The response.
*
* @returns {Error} The created error.
*/
constructor(message, code, config, request, response) {
super(message);
this.name = 'AxiosError';
this.isAxiosError = true;
code && (this.code = code);
config && (this.config = config);
request && (this.request = request);
if (response) {
this.response = response;
this.status = response.status;
/**
* Create an Error with the specified message, config, error code, request and response.
*
* @param {string} message The error message.
* @param {string} [code] The error code (for example, 'ECONNABORTED').
* @param {Object} [config] The config.
* @param {Object} [request] The request.
* @param {Object} [response] The response.
*
* @returns {Error} The created error.
*/
constructor(message, code, config, request, response) {
super(message);
// Make message enumerable to maintain backward compatibility
// The native Error constructor sets message as non-enumerable,
// but axios < v1.13.3 had it as enumerable
Object.defineProperty(this, 'message', {
value: message,
enumerable: true,
writable: true,
configurable: true
});
this.name = 'AxiosError';
this.isAxiosError = true;
code && (this.code = code);
config && (this.config = config);
request && (this.request = request);
if (response) {
this.response = response;
this.status = response.status;
}
}
}
toJSON() {
return {

View File

@ -67,4 +67,26 @@ describe('core::AxiosError', function () {
const err = new AxiosError('test', 'foo', {}, {}, { status: 400 });
expect(err.status).toBe(400);
});
it('should have message property as enumerable for backward compatibility', () => {
const err = new AxiosError('Test error message', 'ERR_TEST', {foo: 'bar'});
// Test Object.keys() includes message
const keys = Object.keys(err);
expect(keys).toContain('message');
// Test Object.entries() includes message
const entries = Object.entries(err);
const messageEntry = entries.find(([key]) => key === 'message');
expect(messageEntry).toBeDefined();
expect(messageEntry[1]).toBe('Test error message');
// Test spread operator includes message
const spread = {...err};
expect(spread.message).toBe('Test error message');
// Verify message descriptor is enumerable
const descriptor = Object.getOwnPropertyDescriptor(err, 'message');
expect(descriptor.enumerable).toBe(true);
});
});