/**
 *  @module     ExternalError
 *  @overview   Defines the `ExternalError` class.
 *  
 *  @author     Animesh Mishra <hello@animesh.ltd>
 *  @copyright  © 2018 Animesh Ltd. All Rights Reserved.
 */

import { Code } from "./Code"

/**
 *  The `ExternalError` class represents errors reported by third-party service
 *  providers the code makes use of. This includes, but is not limited to, Azure
 *  Cosmos database, the SMS provider, the Wallet API and the MVC API.
 *  
 *  An `ExternalError` is always reported with a status code of `Codes.FailedDependency`,
 *  i.e. `424`.
 */
export class ExternalError extends Error {
    public code = Code.FailedDependency
    public message: string
    public help?: string
    public serviceProvider: string

    /**
     *  Initialises an `ExternalError` with a custom error message, the name of the 
     *  service provider or API from where the error originated and an optional debugging
     *  help text.
     *  
     *  @param { string } message           The error message
     *  @param { string } serviceProvider   Name of the service provider or API throwing the error
     *  @param { string } help              Debugging information
     * 
     *  @constructor
     */
    public constructor(message: string, serviceProvider: string, help?: string) {
        super()
        this.message = message
        this.serviceProvider = serviceProvider
        this.help = help
    }

    /**
     *  Sanitises a `ExternalError` object by getting rid of the `code` property. Sending the
     *  `code` property client-side could make the impression that client shouldn't pay 
     *  attention to the HTTP response's `status` header and should code against the response 
     *  body's `code` property instead. That would be a bad design choice.
     * 
     *  @returns { any } A `ExternalError` object without the `code`.
     * 
     *  @function Export
     *  @memberof ExternalError
     *  @instance
     */
    public Export(): any {
        let publicView = JSON.parse(JSON.stringify(this))
        delete publicView.code
        return publicView
    }
}