123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- const npm = {
- u: require('util'),
- os: require('os'),
- utils: require('../utils/static')
- };
- /**
- * @class errors.BatchError
- * @augments external:Error
- * @description
- * This type represents all errors rejected by method {@link batch}, except for {@link external:TypeError TypeError}
- * when the method receives invalid input parameters.
- *
- * @property {string} name
- * Standard {@link external:Error Error} property - error type name = `BatchError`.
- *
- * @property {string} message
- * Standard {@link external:Error Error} property - the error message.
- *
- * It represents the message of the first error encountered in the batch, and is a safe
- * version of using `first.message`.
- *
- * @property {string} stack
- * Standard {@link external:Error Error} property - the stack trace.
- *
- * @property {array} data
- * Array of objects `{success, result, [origin]}`:
- * - `success` = true/false, indicates whether the corresponding value in the input array was resolved.
- * - `result` = resolved data, if `success`=`true`, or else the rejection reason.
- * - `origin` - set only when failed as a result of an unsuccessful call into the notification callback
- * (parameter `cb` of method {@link batch})
- *
- * The array has the same size as the input one that was passed into method {@link batch}, providing direct mapping.
- *
- * @property {} stat
- * Resolution Statistics.
- *
- * @property {number} stat.total
- * Total number of elements in the batch.
- *
- * @property {number} stat.succeeded
- * Number of resolved values in the batch.
- *
- * @property {number} stat.failed
- * Number of rejected values in the batch.
- *
- * @property {number} stat.duration
- * Time in milliseconds it took to settle all values.
- *
- * @property {} first
- * The very first error within the batch, with support for nested batch results, it is also the same error
- * as $[promise.all] would provide.
- *
- * @see {@link batch}
- *
- */
- class BatchError extends Error {
- constructor(result, errors, duration) {
- function getErrors() {
- const err = new Array(errors.length);
- for (let i = 0; i < errors.length; i++) {
- err[i] = result[errors[i]].result;
- if (err[i] instanceof BatchError) {
- err[i] = err[i].getErrors();
- }
- }
- npm.utils.extend(err, '$isErrorList', true);
- return err;
- }
- const e = getErrors();
- let first = e[0];
- while (first && first.$isErrorList) {
- first = first[0];
- }
- let message;
- if (first instanceof Error) {
- message = first.message;
- } else {
- if (typeof first !== 'string') {
- first = npm.u.inspect(first);
- }
- message = first;
- }
- super(message);
- this.name = this.constructor.name;
- this.data = result;
- // we do not show it within the inspect, because when the error
- // happens for a nested result, the output becomes a mess.
- this.first = first;
- this.stat = {
- total: result.length,
- succeeded: result.length - e.length,
- failed: e.length,
- duration: duration
- };
- this.getErrors = getErrors;
- Error.captureStackTrace(this, this.constructor);
- }
- /**
- * @method errors.BatchError.getErrors
- * @description
- * Returns the complete list of errors only.
- *
- * It supports nested batch results, presented as a sub-array.
- *
- * @returns {array}
- */
- }
- /**
- * @method errors.BatchError.toString
- * @description
- * Creates a well-formatted multi-line string that represents the error.
- *
- * It is called automatically when writing the object into the console.
- *
- * The output is an abbreviated version of the error, because the complete error
- * is often too much for displaying or even logging, as a batch can be of any size.
- * Therefore, only errors are rendered from the `data` property, alongside their indexes,
- * and only up to the first 5, to avoid polluting the screen or the log file.
- *
- * @param {number} [level=0]
- * Nested output level, to provide visual offset.
- *
- * @returns {string}
- */
- BatchError.prototype.toString = function (level) {
- level = level > 0 ? parseInt(level) : 0;
- const gap0 = npm.utils.messageGap(level),
- gap1 = npm.utils.messageGap(level + 1),
- gap2 = npm.utils.messageGap(level + 2),
- lines = [
- 'BatchError {',
- gap1 + 'stat: { total: ' + this.stat.total + ', succeeded: ' + this.stat.succeeded +
- ', failed: ' + this.stat.failed + ', duration: ' + this.stat.duration + ' }',
- gap1 + 'errors: ['
- ];
- // In order to avoid polluting the error log or the console,
- // we limit the log output to the top 5 errors:
- const maxErrors = 5;
- let counter = 0;
- this.data.forEach((d, index) => {
- if (!d.success && counter < maxErrors) {
- lines.push(gap2 + index + ': ' + npm.utils.formatError(d.result, level + 2));
- counter++;
- }
- });
- lines.push(gap1 + ']');
- lines.push(gap0 + '}');
- return lines.join(npm.os.EOL);
- };
- npm.utils.addInspection(BatchError, function () {
- return this.toString();
- });
- module.exports = {BatchError};
|