From a75b9b3c8ceeca977b4440738fe4f390a4177dab Mon Sep 17 00:00:00 2001 From: chris48s Date: Sun, 8 Sep 2019 21:58:45 +0100 Subject: [PATCH] document exceptions (#3961) --- core/base-service/errors.js | 84 +++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/core/base-service/errors.js b/core/base-service/errors.js index 14286b1c43..98c0043ebe 100644 --- a/core/base-service/errors.js +++ b/core/base-service/errors.js @@ -1,13 +1,43 @@ +/** + * Standard exceptions for handling error cases + * + * @module + */ + 'use strict' +/** + * Base error class + * + * @abstract + */ class ShieldsRuntimeError extends Error { + /** + * Name of the class. Implementations of ShieldsRuntimeError + * should override this method. + * + * @type {string} + */ get name() { return 'ShieldsRuntimeError' } + + /** + * Default message for this exception if none is specified. + * Implementations of ShieldsRuntimeError should implement this method. + * + * @abstract + * @type {string} + */ get defaultPrettyMessage() { throw new Error('Must implement abstract method') } + /** + * @param {module:core/base-service/errors~RuntimeErrorProps} props + * Refer to individual attrs + * @param {string} message Exception message for debug purposes + */ constructor(props = {}, message) { super(message) this.prettyMessage = props.prettyMessage || this.defaultPrettyMessage @@ -19,6 +49,9 @@ class ShieldsRuntimeError extends Error { const defaultNotFoundError = 'not found' +/** + * Throw this to wrap a 404 or other 'not found' response from an upstream API + */ class NotFound extends ShieldsRuntimeError { get name() { return 'NotFound' @@ -27,6 +60,10 @@ class NotFound extends ShieldsRuntimeError { return defaultNotFoundError } + /** + * @param {module:core/base-service/errors~RuntimeErrorProps} props + * Refer to individual attrs + */ constructor(props = {}) { const prettyMessage = props.prettyMessage || defaultNotFoundError const message = @@ -38,6 +75,9 @@ class NotFound extends ShieldsRuntimeError { } } +/** + * Throw this to wrap an invalid or unexpected response from an upstream API + */ class InvalidResponse extends ShieldsRuntimeError { get name() { return 'InvalidResponse' @@ -46,6 +86,10 @@ class InvalidResponse extends ShieldsRuntimeError { return 'invalid' } + /** + * @param {module:core/base-service/errors~RuntimeErrorProps} props + * Refer to individual attrs + */ constructor(props = {}) { const message = props.underlyingError ? `Invalid Response: ${props.underlyingError.message}` @@ -55,6 +99,10 @@ class InvalidResponse extends ShieldsRuntimeError { } } +/** + * Throw this if we can't contact an upstream API + * or to wrap a 5XX response + */ class Inaccessible extends ShieldsRuntimeError { get name() { return 'Inaccessible' @@ -63,6 +111,10 @@ class Inaccessible extends ShieldsRuntimeError { return 'inaccessible' } + /** + * @param {module:core/base-service/errors~RuntimeErrorProps} props + * Refer to individual attrs + */ constructor(props = {}) { const message = props.underlyingError ? `Inaccessible: ${props.underlyingError.message}` @@ -72,6 +124,9 @@ class Inaccessible extends ShieldsRuntimeError { } } +/** + * Throw this error when required credentials are missing + */ class ImproperlyConfigured extends ShieldsRuntimeError { get name() { return 'ImproperlyConfigured' @@ -80,6 +135,10 @@ class ImproperlyConfigured extends ShieldsRuntimeError { return 'improperly configured' } + /** + * @param {module:core/base-service/errors~RuntimeErrorProps} props + * Refer to individual attrs + */ constructor(props = {}) { const message = props.underlyingError ? `ImproperlyConfigured: ${props.underlyingError.message}` @@ -89,6 +148,10 @@ class ImproperlyConfigured extends ShieldsRuntimeError { } } +/** + * Throw this error when a user supplied input or parameter + * is invalid or unexpected + */ class InvalidParameter extends ShieldsRuntimeError { get name() { return 'InvalidParameter' @@ -97,6 +160,10 @@ class InvalidParameter extends ShieldsRuntimeError { return 'invalid parameter' } + /** + * @param {module:core/base-service/errors~RuntimeErrorProps} props + * Refer to individual attrs + */ constructor(props = {}) { const message = props.underlyingError ? `Invalid Parameter: ${props.underlyingError.message}` @@ -106,6 +173,9 @@ class InvalidParameter extends ShieldsRuntimeError { } } +/** + * Throw this error to indicate that a service is deprecated or removed + */ class Deprecated extends ShieldsRuntimeError { get name() { return 'Deprecated' @@ -114,12 +184,26 @@ class Deprecated extends ShieldsRuntimeError { return 'no longer available' } + /** + * @param {module:core/base-service/errors~RuntimeErrorProps} props + * Refer to individual attrs + */ constructor(props) { const message = 'Deprecated' super(props, message) } } +/** + * @typedef {object} RuntimeErrorProps + * @property {Error} underlyingError Exception we are wrapping (Optional) + * @property {object} response Response from an upstream API to provide + * context for the error (Optional) + * @property {string} prettyMessage User-facing error message to override the + * value of `defaultPrettyMessage()`. This is the text that will appear on the + * badge when we catch and render the exception (Optional) + */ + module.exports = { ShieldsRuntimeError, NotFound,