let options;

/**
 * The base class of all the other exceptions.
 * @extends Error
 */
class Exception extends Error {
	/**
	 * @param {string} [msg] Message
	 * @param {any} [info] Additional information for debug
	 * @param {boolean} [hidesInfo=false] Whether or not to hide `info`
	 */
	constructor(msg = null, info = null, hidesInfo = false) {
		super((msg ? format(msg, info) : format(new.target.message, info)) + ((info && !hidesInfo) ? `\n[${new.target.name}] To debug, catch me and see .info: ${JSON.stringify(info, null, 2)}` : ''));
		this.name = new.target.name;
		this._info = info;
	}
	/**
	 * Additional informations for debug.
	 * @type {any}
	 * @readonly
	 */
	get info() {
		return this._info;
	}
	/**
	 * The default message for this exception class.
	 * @type {string}
	 * @readonly
	 */
	static get message() {
		return '';
	}
	/**
	 * Throws this exception if `handler` option is not set.
	 * If `handler` option is set, calls it and returns the result.
	 * @see Exception.option
	 * @return {any} The result of [option.handler]{@link Exception.option} function
	 * @throws This exception
	 */
	trigger() {
		if (typeof options.handler != 'function') throw this;
		return options.handler(this);
	}
	/**
	 * Returns whether this exception has expected `value` specifically.
	 * @param {any} value An expectation
	 * @return {boolean}
	 * @abstract
	 */
	expects(value) {
		return false; // noop
	}
	/**
	 * Resets all the options to the default values.
	 * @return {class} This exception class
	 */
	static reset() {
		options = {
			handler: null
		};
		return this;
	}
	/**
	 * Returns the value of the option specified by `name`.
	 * If `value` is provided, assigns the value to the option instead of returning it.
	 * You can customize the default behavior of `Exception` at some level by changing the option values.
	 *
	 * ##### Available options:
	 * | Name | Type | Description |
	 * |-----:|:-----|:------------|
	 * | `handler` | function | Runs when [trigger()]{@link Exception#trigger} is called. Receives the triggered exception instance as the argument |
	 *
	 * @param {string} name Option name
	 * @param {any} [value] Option value to set
	 * @return {any|class} The option value, or this exception class if `value` is provided
	 */
	static option(name, value = undefined) {
		if (arguments.length < 2) return options[name];
		options[name] = value;
		return this;
	}
	/**
	 * If `set` is not provided, returns all the current option values in a plain object form.
	 * If `set` is provided, assigns each value in `set` to the option corresponding with the key.
	 * @param {object} [set] Multiple key-value pairs
	 * @return {object|class} The current options in a plain object form, or this exception class if `set` is provided
	 */
	static options(set) {
		if (!arguments.length) return Object.assign({}, options);
		Object.assign(options, set);
		return this;
	}
	/**
	 * Checks whether `value` meets the expected condition varied by each subclass.
	 * @param {any} value A value to check
	 * @return {any} the `value` argument untouched if there's no problem. Otherwise triggers the exception.
	 * @abstract
	 */
	static check(value) {
		return value; // noop
	}
}

function format(str, data) {
	let r = str;
	if (typeof data == 'object') {
		for (let i in data) r = r.replaceAll(`%${i}%`, data[i]);
	}
	return r;
}

Exception.reset();
export default Exception;

Documentation generated by JSDoc 3.6.6
on
using docolatte theme