Source: lib/errors.js

'use strict';

const _ = require('lodash');

// const eyes = require('eyes'), p = _.bind(eyes.inspect, eyes);

/**
 * Object representation of an error that occurred on the server while performing a REST API operation.
 * @deprecated  You should never need to construct one of these directly; they will be provided to callbacks for REST API operations as the first argument if they occur.
 * @extends [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)
 * @memberof module:classeur-api-client
 * @example
 * const ServerError = require('classeur-api-client').ServerError;
 * myClient.getFile('nonexistent', (error) => {
 *     if ( error instanceof ServerError ) {
 *         console.log(error.message); // e.g. 'Server error (400): bad request'
 *         console.log(error.reason); // e.g. 'File name is too short'
 *         console.log(error.status); // e.g. 400
 *         throw error;
 *     }
 * });
 */
class ServerError extends Error {
	/** @lends module:classeur-api-client.ServerError */
	constructor(request, data, response) {
		response = response || '';
		super(`Server error (${data.status || response.statusCode || undefined}): ${data.reason || response.statusMessage || undefined}`);
		if (response) {
			this.response = response;
		}

		/**
		 * A request object as returned by the `get` method of [restler](https://github.com/danwrong/restler).
		 * @summary The HTTP request object that caused the error.
		 * @deprecated  This is usually not useful.
		 * @type {Request}
		 * @instance
		 * @readonly
		 * @see The [restler source]{@link https://github.com/danwrong/restler/blob/master/lib/restler.js} for the Request constructor.
		 */
		this.request = request;
		/**
		 * JSON decoding failures will raise a {@link module:classeur-api-client.ClientError} instead.
		 * @summary The JSON-decoded data send back from the server with the error.
		 * @deprecated  This is usually not useful; the properties `reason`, `status`, and `shortReason` are usually all that is contained in `data`, and they are directly readable.
		 * @type {Object}
		 * @instance
		 * @readonly
		 */
		this.data = data;
		/**
		 * HTTP status code of the error.
		 * @type {Number}
		 * @instance
		 * @readonly
		 */
		this.status = data.status || response.statusCode || null;
		/**
		 * Information sent back by the server indicating why a request failed. This is usually the best source for detailed failure/debugging information.
		 * @type {String}
		 * @instance
		 * @readonly
		 */
		this.reason = data.reason || response.statusMessage || null;
		/**
		 * English version of [ServerError#status]{@link module:classeur-api-client.ServerError#status}.
		 * Usually a short word or phrase explaining what a given error code means in HTTP convention.
		 * @type {String}
		 * @instance
		 * @readonly
		 */
		this.shortReason = data.error || null;
	}
};

/**
 * Object representation of an error that occurred on the client during or after the processing REST API operation.
 * Example causes if a client error (and valid values for the `message` property) inclide:
 * - Request aborted
 * - Request timed out
 * - Corrupt/non-JSON-decodable content received
 *
 * ClientError instances sometimes wrap Restler errors. That means that, in addition to the properties listed below, ClientError instances can contain any properties that Restler attaches to its Error objects for `error`, `abort`, and `timeout` events.
 * @deprecated You should never need to construct one of these directly; they will be provided to callbacks for REST API operations as the first argument if they occur.
 * @extends [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)
 * @memberof module:classeur-api-client
 * @see The [restler documentation](https://github.com/danwrong/restler) for more info on possible Error contents.
 * @example
 * const ClientError = require('classeur-api-client').ClientError;
 * myClient.getFile('nonexistent', (error) => {
 *     if ( error instanceof ClientError ) {
 *         console.log(error.message); // e.g. 'JSON decoding failed!'
 *         throw error;
 *     }
 * });
 */
class ClientError extends Error {
	/** @lends module:classeur-api-client.ClientError*/
	constructor(request, maybeError) {
		let error;
		if ( _.isError(maybeError) ) {
			super(maybeError.message);
			_.merge(this, maybeError);
		} else if ( _.isObject(maybeError) ) {
			super(maybeError.message);
			delete maybeError.message;
			_.merge(this, maybeError);
		} else {
			super(maybeError);
		}
		/**
		 * If a timeout occurred, this property will be set to the timeout threshold that was exceeded (in milliseconds). This property will only be set if a ClientError occurred due to a timeout.
		 * @memberOf module:classeur-api-client.ClientError
		 * @member {Number?} timeout
		 * @instance
		 * @readonly
		 * @see The [restler source]{@link https://github.com/danwrong/restler/blob/master/lib/restler.js} for the Request constructor.
		 */

		/**
		 * A request object as returned by the `get` method of [restler](https://github.com/danwrong/restler).
		 * @summary The HTTP request object that caused the error.
		 * @deprecated  This is usually not useful.
		 * @type {Request}
		 * @instance
		 * @readonly
		 * @see The [restler source]{@link https://github.com/danwrong/restler/blob/master/lib/restler.js} for the Request constructor.
		 */
		this.request = request;
	}
};

module.exports.ServerError = ServerError;
module.exports.ClientError = ClientError;