2020-02-16 15:55:23 +08:00

71 lines
2.1 KiB
TypeScript

import { _ } from './index';
import { IOtterErrorOptions } from './types';
/**
* Fix the prototype chain of the error
*
* Use Object.setPrototypeOf
* Support ES6 environments
*
* Fallback setting __proto__
* Support IE11+, see https://docs.microsoft.com/en-us/scripting/javascript/reference/javascript-version-information
*/
function fixPrototype(target: Error, prototype: {}) {
const setPrototypeOf: typeof Object.setPrototypeOf = (Object as any)
.setPrototypeOf;
setPrototypeOf
? setPrototypeOf(target, prototype)
: ((target as any).__proto__ = prototype);
}
/**
* Capture and fix the error stack when available
*
* Use Error.captureStackTrace
* Support v8 environments
*/
function fixStackTrace(target: Error, fn: any = target.constructor) {
const captureStackTrace: any = (Error as any).captureStackTrace;
if (captureStackTrace) {
captureStackTrace(target, fn);
}
}
class OtterError extends Error {
public name: string = '';
public urlRoot: string = 'https://docs.aimake.io/otter/';
private options: IOtterErrorOptions = {
url: '/',
version: '0.0.0',
};
constructor(message?: string, options?: IOtterErrorOptions) {
super(message);
// set error name as constructor name, make it not enumerable to keep native Error behavior
// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new.target#new.target_in_constructors
Object.defineProperty(this, 'name', {
value: new.target.name,
enumerable: false,
});
// fix the extended error prototype chain
// because typescript __extends implementation can't
// see https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
fixPrototype(this, new.target.prototype);
// try to remove constructor from stack trace
fixStackTrace(this);
_.extend(this.options, options || {});
}
public toString() {
const url = this.urlRoot + this.options.version + this.options.url;
return `${this.name}: ${this.message} See: ${url}`;
}
}
export default OtterError;