"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MissingCreatorError = exports.PartialInstallationError = exports.UIPromptError = exports.ApplicationCompileError = exports.BundlerTSError = exports.ValidationError = exports.assertIsError = exports.transformErrorMessage = exports.wrapError = exports.exitOnError = exports.HiddenError = exports.UserError = exports.BaseError = exports.getErrorAttributes = exports.isUserError = void 0;
const tslib_1 = require("tslib");
const ui_1 = require("../ui");
const Sentry = tslib_1.__importStar(require("@sentry/node"));
const assistant_cli_1 = require("./assistant-cli");
function isErrorWithAnalytics(e) {
    return e.getAttributes !== undefined;
}
function isUserError(e) {
    if (isErrorWithAnalytics(e)) {
        return e.getAttributes().isUserError ?? false;
    }
    if (e.constructor?.name === 'FetchError') {
        if (e.type === 'system') {
            return true;
        }
    }
    return false;
}
exports.isUserError = isUserError;
function getErrorAttributes(e) {
    const result = {};
    if (isErrorWithAnalytics(e)) {
        Object.assign(result, e.getAttributes());
    }
    result.isUserError = isUserError(e);
    return result;
}
exports.getErrorAttributes = getErrorAttributes;
class BaseError extends Error {
    requestId;
    constructor(requestId, message) {
        super(message);
        this.requestId = requestId;
    }
    getAttributes() {
        return {
            isUserError: this.isUserError(),
            requestId: this.requestId
        };
    }
    isUserError() {
        return false;
    }
}
exports.BaseError = BaseError;
class UserError extends BaseError {
    constructor(message, requestId) {
        super(requestId, message);
    }
    isUserError() {
        return true;
    }
}
exports.UserError = UserError;
class HiddenError extends BaseError {
    constructor(message, requestId) {
        super(requestId, message);
    }
}
exports.HiddenError = HiddenError;
function removePrefixFromErrorMessage(message) {
    if (message.startsWith('error: ')) {
        return message.replace('error: ', '');
    }
    return message;
}
const exitOnError = async (logger, error, hint, autoAnalyzeErrorInput) => {
    let exitCode = 0;
    Sentry.withScope((scope) => {
        scope.setTag('userError', isUserError(error));
        scope.setFingerprint(['{{ default }}', '{{ tags.command.name }}']);
        Sentry.captureException(error);
    });
    error.message = removePrefixFromErrorMessage(error.message);
    if (!(error instanceof HiddenError)) {
        logger.error(error);
    }
    if (hint === undefined && !logger.debugEnabled) {
        hint = ui_1.Text.rerunningWithVerbose;
    }
    if (hint) {
        logger.info(hint);
    }
    exitCode = 1;
    await Sentry.close();
    if (autoAnalyzeErrorInput?.prompt && autoAnalyzeErrorInput?.assistantName) {
        await (0, assistant_cli_1.runAssistant)(autoAnalyzeErrorInput.prompt, autoAnalyzeErrorInput.assistantName, logger);
    }
    process.exit(exitCode);
};
exports.exitOnError = exitOnError;
const wrapError = (error) => {
    if (error instanceof Error) {
        return error;
    }
    return new Error(JSON.stringify(error));
};
exports.wrapError = wrapError;
function transformErrorMessage(error, transformFn) {
    const originalMessage = error instanceof Error ? error.message : String(error);
    const message = transformFn(originalMessage);
    return isUserError(error) ? new UserError(message) : new Error(message);
}
exports.transformErrorMessage = transformErrorMessage;
const assertIsError = (error) => {
    if (!(error instanceof Error)) {
        throw new Error(`A non Error type object ${JSON.stringify(error)} of type '${typeof error}' was thrown.`);
    }
};
exports.assertIsError = assertIsError;
class ValidationError extends UserError {
}
exports.ValidationError = ValidationError;
class BundlerTSError extends UserError {
}
exports.BundlerTSError = BundlerTSError;
class ApplicationCompileError extends UserError {
}
exports.ApplicationCompileError = ApplicationCompileError;
class UIPromptError extends BaseError {
    isTtyError;
    constructor(message, isTtyError = false) {
        super(undefined, message);
        this.isTtyError = isTtyError;
    }
    isUserError() {
        return this.isTtyError;
    }
}
exports.UIPromptError = UIPromptError;
class PartialInstallationError extends UserError {
    constructor(message) {
        super(message);
    }
}
exports.PartialInstallationError = PartialInstallationError;
class MissingCreatorError extends BaseError {
    constructor(message) {
        super(message);
    }
}
exports.MissingCreatorError = MissingCreatorError;
