"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.unreachableCheck = exports.UnreachableCheck = exports.StatusError = exports.CustomError = void 0;
exports.isErrorLike = isErrorLike;
exports.asErrorLike = asErrorLike;
/**
 * An easy way to check if an unknown object (e.g. a catch(e) argument) is
 * actually an error-like
 */
function isErrorLike(error) {
    return error && typeof error === 'object' && (error instanceof Error ||
        error.message ||
        error.code ||
        error.stack);
}
/**
 * A convenience method to make something error-ish into an actual Error instance.
 */
function asErrorLike(error) {
    if (isErrorLike(error)) {
        return error;
    }
    else if (error) {
        return new Error(error.message || error.toString() || '[Unknown error]');
    }
    else {
        return new Error('[Undefined error]');
    }
}
// Tiny wrapper to make it super easy to make custom error classes where .name behaves
// correctly, and useful metafields can be easily added.
class CustomError extends Error {
    constructor(message, extras = {}) {
        super(message); // 'Error' breaks prototype chain here
        // This restores the details of the real error subclass:
        this.name = new.target.name;
        Object.setPrototypeOf(this, new.target.prototype);
        if (extras.code !== undefined)
            this.code = extras.code;
        if (extras.statusCode !== undefined)
            this.statusCode = extras.statusCode;
        if (extras.cause !== undefined)
            this.cause = extras.cause;
    }
    code;
    statusCode;
    cause;
}
exports.CustomError = CustomError;
class StatusError extends CustomError {
    constructor(
    /**
     * Should be a valid HTTP status code
     */
    statusCode, message, extras = {}) {
        super(message, { ...extras, statusCode: statusCode });
    }
}
exports.StatusError = StatusError;
/**
 * An error to throw in expected-never cases - by using this, you ask TypeScript to
 * be sure that it agrees that the case is truly unreachable.
 */
class UnreachableCheck extends CustomError {
    // getValue is used to allow logging properties (e.g. v.type) on expected-unreachable
    // values, instead of just logging [object Object].
    constructor(value, getValue = (x => x)) {
        super(`Unhandled case value: ${getValue(value)}`);
    }
}
exports.UnreachableCheck = UnreachableCheck;
/**
 * A convenient expression-shaped version of UnreachableCheck
 */
const unreachableCheck = (value, getValue = (x => x)) => {
    throw new UnreachableCheck(value, getValue);
};
exports.unreachableCheck = unreachableCheck;
//# sourceMappingURL=errors.js.map