"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BringgException = exports.logOnException = void 0;
var lodash_1 = __importDefault(require("lodash"));
var extendable_error_1 = require("../extendable-error");
var ExceptionReason_1 = require("./ExceptionReason");
var Logger_1 = __importDefault(require("./Logger"));
var logOnException = function (target, propertyKey, descriptor) {
    var originalMethod = descriptor.value;
    descriptor.value = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        try {
            var result = originalMethod.apply(this, args);
            var isPromise = result && result.then;
            return isPromise ? result.catch(handleError) : result;
        }
        catch (e) {
            handleError(e);
        }
    };
    return descriptor;
};
exports.logOnException = logOnException;
function handleError(e) {
    try {
        Logger_1.default.error(e);
    }
    catch (e) {
        //
    }
    if (e instanceof BringgException) {
        throw e;
    }
    throw new BringgException(ExceptionReason_1.ExceptionReason.UNCAUGHT, e.message, e);
}
var toStringProducer = function (messageProducer) {
    if (lodash_1.default.isUndefined(messageProducer)) {
        return null;
    }
    if (lodash_1.default.isFunction(messageProducer)) {
        return messageProducer;
    }
    return function () { return messageProducer.toString(); };
};
var BringgException = /** @class */ (function (_super) {
    __extends(BringgException, _super);
    function BringgException(reason, messageProducer, error, data) {
        var _this = _super.call(this) || this;
        _this.data = data;
        _this.reason = reason;
        _this.error = error;
        _this.messageProducer = toStringProducer(messageProducer) || (function () { return reason.name; });
        _this._details = function () { return undefined; };
        return _this;
    }
    Object.defineProperty(BringgException.prototype, "message", {
        get: function () {
            try {
                return this.messageProducer();
            }
            catch (e) {
                Logger_1.default.error('caught exception while trying to produce error message...');
            }
        },
        /**
         * pass message producer instead, this is a NoOp
         */
        set: function (value) {
            //
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(BringgException.prototype, "details", {
        get: function () {
            try {
                return this._details();
            }
            catch (e) {
                Logger_1.default.error('caught exception while trying to produce error details...');
            }
        },
        set: function (details) {
            var _this = this;
            this._details = toStringProducer(details) || (function () { return _this.message; });
        },
        enumerable: false,
        configurable: true
    });
    BringgException.serviceException = function (message) {
        return function () { return new BringgException(ExceptionReason_1.ExceptionReason.UNSUCCESSFUL_RESULT, message); };
    };
    return BringgException;
}(extendable_error_1.ExtendableError));
exports.BringgException = BringgException;
//# sourceMappingURL=BringgException.js.map