axios-better-stacktrace
Advanced tools
Comparing version 1.2.0 to 2.0.0
@@ -5,2 +5,13 @@ # Changelog | ||
## [2.0.0](https://github.com/svsool/axios-better-stacktrace/compare/v1.2.0...v2.0.0) (2021-02-14) | ||
### ⚠ BREAKING CHANGES | ||
* `exposeTopmostErrorViaConfig` option was removed | ||
### Features | ||
* Enhance error in the response interceptor automatically ([64a2e76](https://github.com/svsool/axios-better-stacktrace/commit/64a2e76b3e2206f238d7794b4ead544474ebfc08)) | ||
## [1.2.0](https://github.com/svsool/axios-better-stacktrace/compare/v1.1.0...v1.2.0) (2021-02-07) | ||
@@ -7,0 +18,0 @@ |
@@ -6,7 +6,9 @@ import { AxiosInstance } from 'axios'; | ||
} | ||
interface AxiosError { | ||
originalStack?: string; | ||
} | ||
} | ||
declare const axiosBetterStacktrace: (axiosInstance?: AxiosInstance | undefined, opts?: { | ||
errorMsg?: string | undefined; | ||
exposeTopmostErrorViaConfig?: boolean | undefined; | ||
}) => (() => void) | undefined; | ||
export default axiosBetterStacktrace; |
@@ -14,2 +14,6 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var patchedSym = Symbol('axiosBetterStacktrace.patched'); | ||
var isAxiosError = function (error) { | ||
return error instanceof Error && error.isAxiosError !== undefined; | ||
}; | ||
var axiosMethods = [ | ||
@@ -25,43 +29,28 @@ 'request', | ||
]; | ||
var axiosBetterStacktraceHandler = function (params, topmostError, exposeTopmostErrorViaConfig) { | ||
// extend config with topmostError which can be used | ||
// inside interceptor callbacks (e.g. for logging purposes) | ||
var handlerResult = (function () { | ||
switch (params.method) { | ||
case 'request': { | ||
var originalHandler = params.originalHandler, config = params.args[0]; | ||
return originalHandler(exposeTopmostErrorViaConfig | ||
? __assign(__assign({}, (config || {})), { topmostError: topmostError }) : config); | ||
} | ||
case 'get': | ||
case 'delete': | ||
case 'head': | ||
case 'options': { | ||
var originalHandler = params.originalHandler, _a = params.args, url = _a[0], config = _a[1]; | ||
return originalHandler(url, exposeTopmostErrorViaConfig | ||
? __assign(__assign({}, (config || {})), { topmostError: topmostError }) : config); | ||
} | ||
case 'post': | ||
case 'put': | ||
case 'patch': { | ||
var originalHandler = params.originalHandler, _b = params.args, url = _b[0], data = _b[1], config = _b[2]; | ||
return originalHandler(url, data, exposeTopmostErrorViaConfig | ||
? __assign(__assign({}, (config || {})), { topmostError: topmostError }) : config); | ||
} | ||
// inherits original axios handler generics https://github.com/axios/axios/blob/79979d9214601478b67a330fc144cad25c59f3c7/index.d.ts#L139-L146 | ||
var axiosBetterStacktraceHandler = function (params, topmostError) { | ||
// extends request config with topmostError, so it could be used inside an interceptor to enhance original error | ||
switch (params.method) { | ||
case 'request': { | ||
var originalHandler = params.originalHandler, config = params.args[0]; | ||
return originalHandler(__assign(__assign({}, (config || {})), { topmostError: topmostError })); | ||
} | ||
})(); | ||
// extend axios original handlers with a catch block which augments original error with a better stack trace | ||
return handlerResult.catch(function (maybeError) { | ||
if (maybeError instanceof Error) { | ||
var error = maybeError; | ||
error.originalStack = maybeError.stack; | ||
error.stack = error.stack + "\n" + topmostError.stack; | ||
throw error; | ||
case 'get': | ||
case 'delete': | ||
case 'head': | ||
case 'options': { | ||
var originalHandler = params.originalHandler, _a = params.args, url = _a[0], config = _a[1]; | ||
return originalHandler(url, __assign(__assign({}, (config || {})), { topmostError: topmostError })); | ||
} | ||
return maybeError; | ||
}); | ||
case 'post': | ||
case 'put': | ||
case 'patch': { | ||
var originalHandler = params.originalHandler, _b = params.args, url = _b[0], data = _b[1], config = _b[2]; | ||
return originalHandler(url, data, __assign(__assign({}, (config || {})), { topmostError: topmostError })); | ||
} | ||
} | ||
}; | ||
var axiosBetterStacktrace = function (axiosInstance, opts) { | ||
if (opts === void 0) { opts = {}; } | ||
var _a = opts.errorMsg, errorMsg = _a === void 0 ? 'Axios Better Stacktrace' : _a, _b = opts.exposeTopmostErrorViaConfig, exposeTopmostErrorViaConfig = _b === void 0 ? false : _b; | ||
var _a = opts.errorMsg, errorMsg = _a === void 0 ? 'Axios Better Stacktrace' : _a; | ||
// do nothing if input does not look like an axios instance | ||
@@ -72,12 +61,26 @@ if (!axiosInstance || !axiosMethods.some(function (method) { return axiosInstance.hasOwnProperty(method); })) { | ||
// avoid potential memory leaks if axios instance already patched | ||
if (axiosInstance.__axiosBetterStacktracePatched) { | ||
if (axiosInstance[patchedSym]) { | ||
return; | ||
} | ||
// ensure original handlers can be restored after patching | ||
var originalHandlersByMethod = axiosMethods.reduce(function (acc, method) { | ||
if (method in axiosInstance) { | ||
acc[method] = axiosInstance[method]; | ||
var originalHandlers = { | ||
request: axiosInstance['request'], | ||
get: axiosInstance['get'], | ||
delete: axiosInstance['delete'], | ||
head: axiosInstance['head'], | ||
options: axiosInstance['options'], | ||
post: axiosInstance['post'], | ||
put: axiosInstance['put'], | ||
patch: axiosInstance['patch'], | ||
}; | ||
// enhance original error with a topmostError stack trace | ||
axiosInstance.interceptors.response.use(undefined, function (error) { | ||
if (isAxiosError(error) && error.config && error.config.topmostError instanceof Error) { | ||
error.originalStack = error.stack; | ||
error.stack = error.stack + "\n" + error.config.topmostError.stack; | ||
// remove topmostError to not clutter config and expose it to other interceptors down the chain | ||
delete error.config.topmostError; | ||
throw error; | ||
} | ||
return acc; | ||
}, {}); | ||
throw error; | ||
}); | ||
axiosMethods.forEach(function (method) { | ||
@@ -93,3 +96,3 @@ if (method in axiosInstance) { | ||
args: [config], | ||
}, new Error(errorMsg), exposeTopmostErrorViaConfig); | ||
}, new Error(errorMsg)); | ||
}; | ||
@@ -108,3 +111,3 @@ break; | ||
args: [url, config], | ||
}, new Error(errorMsg), exposeTopmostErrorViaConfig); | ||
}, new Error(errorMsg)); | ||
}; | ||
@@ -122,3 +125,3 @@ break; | ||
args: [url, data, config], | ||
}, new Error(errorMsg), exposeTopmostErrorViaConfig); | ||
}, new Error(errorMsg)); | ||
}; | ||
@@ -128,4 +131,4 @@ break; | ||
} | ||
if (!axiosInstance.__axiosBetterStacktracePatched) { | ||
axiosInstance.__axiosBetterStacktracePatched = true; | ||
if (!axiosInstance[patchedSym]) { | ||
axiosInstance[patchedSym] = true; | ||
} | ||
@@ -136,5 +139,3 @@ } | ||
var restoreOriginalHandlers = function () { | ||
Object.keys(originalHandlersByMethod).forEach(function (method) { | ||
axiosInstance[method] = originalHandlersByMethod[method]; | ||
}); | ||
Object.assign(axiosInstance, originalHandlers); | ||
}; | ||
@@ -141,0 +142,0 @@ return restoreOriginalHandlers; |
@@ -14,3 +14,3 @@ { | ||
"author": "Svyatoslav Sobol <svyatoslav.sobol@gmail.com>", | ||
"version": "1.2.0", | ||
"version": "2.0.0", | ||
"main": "lib/axiosBetterStacktrace.js", | ||
@@ -17,0 +17,0 @@ "types": "lib/axiosBetterStacktrace.d.ts", |
@@ -37,21 +37,23 @@ # axios-better-stacktrace | ||
// Example 1 | ||
// use it before any other interceptors | ||
axiosBetterStacktrace(axiosAgent); | ||
// response error will get an enhanced stack trace inside a catch block automatically | ||
axios.get('https://npmjs.com/<not-found>/').catch(enhancedError => console.error(enhancedError)); | ||
// when using promises response error will get an enhanced stack trace automatically | ||
axiosAgent.get('https://npmjs.com/<not-found>/').catch(enhancedError => console.error(enhancedError)); | ||
// Example 2 | ||
// or using async/await | ||
(async () => { | ||
try { | ||
await axiosAgent.get('https://npmjs.com/<not-found>/'); | ||
} catch (enhancedError) { | ||
console.error(enhancedError); | ||
} | ||
})(); | ||
// enhanced error can also be accessed inside an interceptor callback (e.g. for logging purposes) | ||
axiosBetterStacktrace(axiosAgent, { exposeTopmostErrorViaConfig: true }); | ||
// or using a response interceptor and an error callback (e.g. could be useful with a logging middleware) | ||
axiosAgent.interceptors.response.use(config => config, enhancedError => { | ||
console.error(enhancedError); | ||
axios.interceptors.response.use(config => config, (result) => { | ||
console.error(result.config.topmostError); | ||
return result; | ||
}); | ||
axios.get('https://npmjs.com/<not-found>/'); | ||
``` | ||
@@ -64,3 +66,2 @@ | ||
| errorMsg | `String` | `Axios Better Stacktrace` | Error message to show next to the original one in the output. | | ||
| exposeTopmostErrorViaConfig | `Boolean` | `false` | Whether to expose enhanced error as `config.topmostError`. See [this issue](https://github.com/svsool/axios-better-stacktrace/issues/1) for reference. | | ||
@@ -67,0 +68,0 @@ ## Example |
Sorry, the diff of this file is not supported yet
17284
149
102