@naturalcycles/nodejs-lib
Version:
Standard library for Node.js
117 lines • 4.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const js_lib_1 = require("@naturalcycles/js-lib");
const got_1 = require("got");
const __1 = require("..");
const colors_1 = require("../colors");
/**
* Returns instance of Got with "reasonable defaults":
*
* 1. Error handler hook that prints helpful errors.
* 2. Hooks that log start/end of request (optional, false by default).
*/
function getGot(opt = {}) {
return got_1.default.extend({
hooks: {
beforeError: [gotErrorHook(opt)],
beforeRequest: [gotBeforeRequestHook(opt)],
afterResponse: [gotAfterResponseHook(opt)],
},
});
}
exports.getGot = getGot;
/**
* Without this hook (default behaviour):
*
* HTTPError: Response code 422 (Unprocessable Entity)
* at EventEmitter.<anonymous> (.../node_modules/got/dist/source/as-promise.js:118:31)
* at processTicksAndRejections (internal/process/task_queues.js:97:5) {
* name: 'HTTPError'
*
*
* With this hook:
*
* HTTPError 422 GET http://a.com/err?q=1 in 8 ms
* {
* message: 'Reference already exists',
* documentation_url: 'https://developer.github.com/v3/git/refs/#create-a-reference'
* }
*
* Features:
* 1. Includes original method and URL (including e.g searchParams) in the error message.
* 2. Includes response.body in the error message (limited length).
* 3. Auto-detects and parses JSON response body (limited length).
* 4. Includes time spent (gotBeforeRequestHook must also be enabled).
*/
function gotErrorHook(opt = {}) {
const { maxResponseLength = 10000 } = opt;
return err => {
if (err instanceof got_1.HTTPError) {
const { statusCode } = err.response;
const { method, url, context } = err.options;
const { started } = context;
// Auto-detect and prettify JSON response (if any)
let body = js_lib_1._jsonParseIfPossible(err.response.body);
// Detect HttpErrorResponse
if (js_lib_1._isHttpErrorResponse(body)) {
body = body.error;
}
body = __1.inspectAny(body, {
maxLen: maxResponseLength,
colors: false,
});
err.message = [
[statusCode, method, url, started && `in ${js_lib_1._since(started)}`].filter(Boolean).join(' '),
body,
]
.filter(Boolean)
.join('\n');
}
return err;
};
}
exports.gotErrorHook = gotErrorHook;
function gotBeforeRequestHook(opt = {}) {
return options => {
options.context = {
...options.context,
started: Date.now(),
};
if (opt.logStart) {
console.log([colors_1.dimGrey(' >>'), colors_1.dimGrey(options.method), colors_1.grey(options.url)].join(' '));
}
};
}
exports.gotBeforeRequestHook = gotBeforeRequestHook;
function gotAfterResponseHook(opt = {}) {
return resp => {
const success = resp.statusCode >= 200 && resp.statusCode < 400;
if (opt.logFinished) {
const { started } = resp.request.options.context;
console.log([
colors_1.dimGrey(' <<'),
coloredHttpCode(resp.statusCode),
colors_1.dimGrey(resp.request.options.method),
colors_1.grey(resp.request.options.url),
started && colors_1.dimGrey('in ' + js_lib_1._since(started)),
]
.filter(Boolean)
.join(' '));
// console.log(`afterResp! ${resp.request.options.method} ${resp.url}`, { context: resp.request.options.context })
}
// Error responses are not logged, cause they're included in Error message already
if (opt.logResponse && success) {
console.log(__1.inspectAny(js_lib_1._jsonParseIfPossible(resp.body), { maxLen: opt.maxResponseLength }));
}
return resp;
};
}
exports.gotAfterResponseHook = gotAfterResponseHook;
function coloredHttpCode(statusCode) {
if (statusCode < 400)
return colors_1.dimGrey(statusCode); // default
if (statusCode < 500)
return colors_1.yellow(statusCode);
return colors_1.red(statusCode);
}
//# sourceMappingURL=got.hooks.js.map