"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractCodeAndMessageFromJsonRpcError = extractCodeAndMessageFromJsonRpcError;
exports.extractErrorDetails = extractErrorDetails;
exports.shallowExtractErrorDetails = shallowExtractErrorDetails;
exports.shallowExtractErrorDetailsJSON = shallowExtractErrorDetailsJSON;
exports.extractExecutionRevertedError = extractExecutionRevertedError;
const logger_1 = require("./logger");
function isErrorWithBody(error) {
    return typeof error === 'object' && error !== null && 'body' in error;
}
function parseErrorBody(body) {
    if (typeof body !== 'string')
        return;
    try {
        return JSON.parse(body);
    }
    catch (error) {
        logger_1.logger.error({ error: error.message || '' }, 'Failed to parse error body');
    }
}
/**
 * Extracts error code and message from a JSON-RPC error response.
 *
 * @param {unknown} error - The error object
 * @return {ErrorResponse} - An object with the error code, message, and body.
 */
function extractCodeAndMessageFromJsonRpcError(error) {
    if (!error) {
        return { code: 400, message: '', errorBody: {} };
    }
    const typedError = error;
    const parsedBody = isErrorWithBody(error) ? parseErrorBody(typedError.body) : undefined;
    const parsedError = parsedBody?.error;
    return parsedError
        ? {
            code: parsedError.code || typedError.code || 500,
            message: parsedError.message || typedError.message || '',
            errorBody: parsedError,
        }
        : {
            code: typedError.code || 500,
            message: typedError.message || (isErrorWithBody(error) ? String(typedError.body) : 'An unknown error occurred'),
            errorBody: {},
        };
}
/**
 * Parses an error message string to extract 'reason', 'method', and 'code' details.
 *
 * @return {ErrorDetails} - An object containing the extracted details.
 * @param _error
 */
function extractErrorDetails(_error) {
    if (!_error) {
        return { reason: '', method: '', code: '', message: '' };
    }
    const error = _error; // unsafe, but TS errors are super hard to deal with
    const message = error?.message || ''; // message pulled from top level error for backwards compatibility
    const nestedError = error?.error?.error || error?.error || error;
    const method = error?.error?.method || error?.method || ''; // method is always pulled from error above
    // Handle errors with body property
    if (nestedError.body) {
        const { code, message, errorBody } = extractCodeAndMessageFromJsonRpcError(nestedError);
        return { reason: message, method, code, errorBody, message };
    }
    // @TODO: When checking for body-less errors, we reverse checking order - unsure if this is intentional?
    if (error?.code && error.method && error.reason) {
        return {
            reason: error.reason,
            method: error.method,
            code: error.code,
            message,
        };
    }
    if (error?.error?.code && error.error.reason && error.error.method) {
        return {
            reason: error.error.reason,
            method: error.error.method,
            code: error.error.code,
            message,
        };
    }
    const errorString = error?.message ?? '';
    const reasonMatch = errorString.match(/reason="([^"]+)"/);
    const methodMatch = errorString.match(/method="([^"]+)"/);
    const codeMatch = errorString.match(/code=([^,]+)/);
    return {
        reason: reasonMatch ? reasonMatch[1].replaceAll(/(^"|"$)/g, '') : '', // remove leading and trailing quotes
        method: methodMatch ? methodMatch[1].replaceAll(/(^"|"$)/g, '') : '',
        code: codeMatch ? codeMatch[1].replaceAll(/(^"|"$)/g, '') : '',
        message,
    };
}
/**
 *
 * Ensures that nested errors are ignored.
 *
 * @param _error
 */
function shallowExtractErrorDetails(_error) {
    if (!_error) {
        return { reason: '', method: '', code: '', message: '' };
    }
    try {
        const error = _error; // unsafe, but TS errors are super hard to deal with
        return {
            reason: error.reason,
            method: error.method,
            code: error.code,
            message: error.message,
        };
    }
    catch {
        return { reason: '', method: '', code: '', message: '' };
    }
}
function shallowExtractErrorDetailsJSON(error) {
    return JSON.stringify(shallowExtractErrorDetails(error), null, 2);
}
function extractExecutionRevertedError(input) {
    // Use a regular expression to match the pattern
    const regex = /reverted:\s*(\w+#\d+)/;
    const match = regex.exec(input);
    // Check if a match was found and return the captured group
    return match?.[1] || null;
}
//# sourceMappingURL=error.js.map