Skip to content

Commit

Permalink
DRAFT
Browse files Browse the repository at this point in the history
  • Loading branch information
DigitalBrainJS committed Oct 14, 2021
1 parent 77eaac9 commit a3f0cfa
Show file tree
Hide file tree
Showing 17 changed files with 150 additions and 74 deletions.
26 changes: 22 additions & 4 deletions index.d.ts
Expand Up @@ -121,16 +121,34 @@ export interface AxiosResponse<T = unknown, D = any> {
request?: any;
}

export interface AxiosError<T = unknown, D = any> extends Error {
export class AxiosError<T = unknown, D = any> extends Error {
constructor(
message?: string,
code?: string,
config?: AxiosRequestConfig<D>,
request?: any,
response?: AxiosResponse<T, D>
);
config: AxiosRequestConfig<D>;
code?: string;
request?: any;
response?: AxiosResponse<T, D>;
isAxiosError: boolean;
status?: string;
toJSON: () => object;
}

export interface CanceledError<T> extends AxiosError<T>{
static readonly ERR_FR_TOO_MANY_REDIRECTS = "ERR_FR_TOO_MANY_REDIRECTS";
static readonly ERR_BAD_OPTION_VALUE = "ERR_BAD_OPTION_VALUE";
static readonly ERR_BAD_OPTION = "ERR_BAD_OPTION";
static readonly ERR_NETWORK = "ERR_NETWORK";
static readonly ERR_DEPRECATED = "ERR_DEPRECATED";
static readonly ERR_BAD_RESPONSE = "ERR_BAD_RESPONSE";
static readonly ERR_BAD_REQUEST = "ERR_BAD_REQUEST";
static readonly ERR_CANCELED = "ERR_CANCELED";
static readonly ECONNABORTED = "ECONNABORTED";
static readonly ETIMEDOUT = "ETIMEDOUT";
}

export class CanceledError<T> extends AxiosError<T> {
}

export interface AxiosPromise<T = unknown> extends Promise<AxiosResponse<T>> {
Expand Down
21 changes: 10 additions & 11 deletions lib/adapters/http.js
Expand Up @@ -11,11 +11,9 @@ var httpsFollow = require('follow-redirects').https;
var url = require('url');
var zlib = require('zlib');
var VERSION = require('./../env/data').version;
var createError = require('../core/createError');
var enhanceError = require('../core/enhanceError');
var defaults = require('../defaults');
var Cancel = require('../cancel/Cancel');
var AxiosError = require('../core/AxiosError');
var CanceledError = require('../cancel/CanceledError');

var isHttps = /https:?/;

Expand Down Expand Up @@ -96,6 +94,7 @@ module.exports = function httpAdapter(config) {
} else {
return reject(new AxiosError(
'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream',
AxiosError.ERR_BAD_REQUEST,
config
));
}
Expand Down Expand Up @@ -272,13 +271,13 @@ module.exports = function httpAdapter(config) {
if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {
stream.destroy();
reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',
config, null, lastRequest));
AxiosError.ERR_BAD_RESPONSE, config, lastRequest));
}
});

stream.on('error', function handleStreamError(err) {
if (req.aborted) return;
reject(AxiosError.from(err, config, null, lastRequest));
reject(AxiosError.from(err, null, config, lastRequest));
});

stream.on('end', function handleStreamEnd() {
Expand All @@ -298,8 +297,8 @@ module.exports = function httpAdapter(config) {

// Handle errors
req.on('error', function handleRequestError(err) {
if (req.aborted && err.code !== 'ERR_FR_TOO_MANY_REDIRECTS') return;
reject(AxiosError.from(err, config, null, req));
if (req.aborted && err.code !== AxiosError.ERR_FR_TOO_MANY_REDIRECTS) return;
reject(AxiosError.from(err, null, config, req));
});

// Handle request timeout
Expand All @@ -308,10 +307,10 @@ module.exports = function httpAdapter(config) {
var timeout = parseInt(config.timeout, 10);

if (isNaN(timeout)) {
reject(createError(
reject(new AxiosError(
'error trying to parse `config.timeout` to int',
AxiosError.ERR_BAD_OPTION_VALUE,
config,
'ERR_PARSE_TIMEOUT',
req
));

Expand All @@ -328,8 +327,8 @@ module.exports = function httpAdapter(config) {
var transitional = config.transitional || defaults.transitional;
reject(new AxiosError(
'timeout of ' + timeout + 'ms exceeded',
transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,
config,
transitional.clarifyTimeoutError ? 'ETIMEDOUT' : 'ECONNABORTED',
req
));
});
Expand All @@ -344,7 +343,7 @@ module.exports = function httpAdapter(config) {
req.abort();
cancel.config = config;
cancel.request = req;
reject(!cancel || (cancel && cancel.type) ? new Cancel('canceled') : cancel);
reject(!cancel || (cancel && cancel.type) ? new CanceledError() : cancel);
};

config.cancelToken && config.cancelToken.subscribe(onCanceled);
Expand Down
11 changes: 5 additions & 6 deletions lib/adapters/xhr.js
Expand Up @@ -7,10 +7,9 @@ var buildURL = require('./../helpers/buildURL');
var buildFullPath = require('../core/buildFullPath');
var parseHeaders = require('./../helpers/parseHeaders');
var isURLSameOrigin = require('./../helpers/isURLSameOrigin');
var createError = require('../core/createError');
var defaults = require('../defaults');
var Cancel = require('../cancel/Cancel');
var AxiosError = require('../core/AxiosError');
var CanceledError = require('../cancel/CanceledError');

module.exports = function xhrAdapter(config) {
return new Promise(function dispatchXhrRequest(resolve, reject) {
Expand Down Expand Up @@ -105,7 +104,7 @@ module.exports = function xhrAdapter(config) {
return;
}

reject(new AxiosError('Request aborted', config, 'ECONNABORTED', request));
reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));

// Clean up request
request = null;
Expand All @@ -115,7 +114,7 @@ module.exports = function xhrAdapter(config) {
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', config, null, request));
reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request, request));

// Clean up request
request = null;
Expand All @@ -130,8 +129,8 @@ module.exports = function xhrAdapter(config) {
}
reject(new AxiosError(
timeoutErrorMessage,
transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,
config,
transitional.clarifyTimeoutError ? 'ETIMEDOUT' : 'ECONNABORTED',
request));

// Clean up request
Expand Down Expand Up @@ -192,7 +191,7 @@ module.exports = function xhrAdapter(config) {
if (!request) {
return;
}
reject(!cancel || (cancel && cancel.type) ? new AxiosCancel('canceled') : cancel);
reject(!cancel || (cancel && cancel.type) ? new CanceledError() : cancel);
request.abort();
request = null;
};
Expand Down
2 changes: 1 addition & 1 deletion lib/axios.js
Expand Up @@ -37,7 +37,7 @@ var axios = createInstance(defaults);
axios.Axios = Axios;

// Expose Cancel & CancelToken
axios.Cancel = require('./cancel/Cancel');
axios.CanceledError = require('./cancel/CanceledError');
axios.CancelToken = require('./cancel/CancelToken');
axios.isCancel = require('./cancel/isCancel');
axios.VERSION = require('./env/data').version;
Expand Down
4 changes: 3 additions & 1 deletion lib/cancel/CanceledError.js
Expand Up @@ -10,7 +10,9 @@ var utils = require('../utils');
* @param {string=} message The message.
*/
function CanceledError(message) {
AxiosError.call(this, message, null, 'ECONNABORTED');
// eslint-disable-next-line no-eq-null,eqeqeq
AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED);
this.name = 'CanceledError';
}

utils.inherits(CanceledError, AxiosError, {
Expand Down
62 changes: 34 additions & 28 deletions lib/core/AxiosError.js
Expand Up @@ -6,20 +6,20 @@ var utils = require('../utils');
* Create an Error with the specified message, config, error code, request and response.
*
* @param {string} message The error message.
* @param {Object} config The config.
* @param {string?} [code] The error code (for example, 'ECONNABORTED').
* @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.
*/
function AxiosError(message, config, code, request, response) {
function AxiosError(message, code, config, request, response) {
Error.call(this);
this.message = message;
this.name = this.constructor.name;
this.config = config;
this.name = 'AxiosError';
code && (this.code = code);
this.request = request;
this.response = response;
config && (this.config = config);
request && (this.request = request);
response && (this.response = response);
}

utils.inherits(AxiosError, Error, {
Expand All @@ -38,42 +38,48 @@ utils.inherits(AxiosError, Error, {
stack: this.stack,
// Axios
config: this.config,
code: this.code
code: this.code,
status: this.response && this.response.status ? this.response.status : null
};
}
});

var prototype = AxiosError.prototype;
var descriptors = {};

[
'ERR_BAD_OPTION_VALUE',
'ERR_BAD_OPTION',
'ECONNABORTED',
'ETIMEDOUT',
'ERR_NETWORK',
'ERR_FR_TOO_MANY_REDIRECTS',
'ERR_DEPRECATED',
'ERR_BAD_RESPONSE',
'ERR_BAD_REQUEST',
'ERR_CANCELED'
// eslint-disable-next-line func-names
].forEach(function(code) {
descriptors[code] = {value: code};
});

Object.defineProperties(AxiosError, descriptors);
Object.defineProperty(prototype, 'isAxiosError', {value: true});

// eslint-disable-next-line func-names
AxiosError.from = function(error, config, code, request, response) {
AxiosError.from = function(error, code, config, request, response, customProps) {
var axiosError = Object.create(prototype);

var props;
var i;
var prop;
var obj = error;
var merged = {};
utils.toFlatObject(error, axiosError, function filter(obj) {
return obj !== Error.prototype;
});

do {
props = Object.getOwnPropertyNames(obj);
i = props.length;
while (i-- > 0) {
prop = props[i];
if (!merged[prop]) {
axiosError[prop] = obj[prop];
merged[prop] = true;
}
}
obj = Object.getPrototypeOf(obj);
} while (obj && obj !== Error.prototype && obj !== Object.prototype);

AxiosError.call(axiosError, error.message, config, code, request, response);
AxiosError.call(axiosError, error.message, code, config, request, response);

axiosError.name = error.name;

customProps && Object.assign(axiosError, customProps);

return axiosError;
};

Expand Down
4 changes: 2 additions & 2 deletions lib/core/dispatchRequest.js
Expand Up @@ -4,7 +4,7 @@ var utils = require('./../utils');
var transformData = require('./transformData');
var isCancel = require('../cancel/isCancel');
var defaults = require('../defaults');
var Cancel = require('../cancel/Cancel');
var CanceledError = require('../cancel/CanceledError');

/**
* Throws a `CanceledError` if cancellation has been requested.
Expand All @@ -15,7 +15,7 @@ function throwIfCancellationRequested(config) {
}

if (config.signal && config.signal.aborted) {
throw new Cancel('canceled');
throw new CanceledError();
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/core/settle.js
Expand Up @@ -16,8 +16,8 @@ module.exports = function settle(resolve, reject, response) {
} else {
reject(new AxiosError(
'Request failed with status code ' + response.status,
[AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],
response.config,
null,
response.request,
response
));
Expand Down
4 changes: 2 additions & 2 deletions lib/defaults.js
Expand Up @@ -2,7 +2,7 @@

var utils = require('./utils');
var normalizeHeaderName = require('./helpers/normalizeHeaderName');
var enhanceError = require('./core/enhanceError');
var AxiosError = require('./core/AxiosError');

var DEFAULT_CONTENT_TYPE = {
'Content-Type': 'application/x-www-form-urlencoded'
Expand Down Expand Up @@ -90,7 +90,7 @@ var defaults = {
} catch (e) {
if (strictJSONParsing) {
if (e.name === 'SyntaxError') {
throw enhanceError(e, this, 'E_JSON_PARSE');
throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);
}
throw e;
}
Expand Down
12 changes: 8 additions & 4 deletions lib/helpers/validator.js
@@ -1,6 +1,7 @@
'use strict';

var VERSION = require('../env/data').version;
var AxiosError = require('../core/AxiosError');

var validators = {};

Expand Down Expand Up @@ -28,7 +29,10 @@ validators.transitional = function transitional(validator, version, message) {
// eslint-disable-next-line func-names
return function(value, opt, opts) {
if (validator === false) {
throw new Error(formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')));
throw new AxiosError(
formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),
AxiosError.ERR_DEPRECATED
);
}

if (version && !deprecatedWarnings[opt]) {
Expand All @@ -55,7 +59,7 @@ validators.transitional = function transitional(validator, version, message) {

function assertOptions(options, schema, allowUnknown) {
if (typeof options !== 'object') {
throw new TypeError('options must be an object');
throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);
}
var keys = Object.keys(options);
var i = keys.length;
Expand All @@ -66,12 +70,12 @@ function assertOptions(options, schema, allowUnknown) {
var value = options[opt];
var result = value === undefined || validator(value, opt, options);
if (result !== true) {
throw new TypeError('option ' + opt + ' must be ' + result);
throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);
}
continue;
}
if (allowUnknown !== true) {
throw Error('Unknown option ' + opt);
throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);
}
}
}
Expand Down

0 comments on commit a3f0cfa

Please sign in to comment.