import { Logger } from "../logger";
import { System } from "../../common/system";
import { Globals } from "../../common/Globals";
/**
 * Captures console.error messages and then copying them to the central logger by monkey-patching the global console.
 *
 * This is primarily a system for capturing unexpected errors such as react errors during internal e2e testing.
 * The console is therefore not monkey-patched in browser views because those contain customer apps.
 */
const maybeSendConsoleErrorsToCentralLogger = () => {
    if (globalThis.console.unwrappedError)
        return; // already wrapped
    if (globalThis.glue42gd)
        return; // If running under iocd then don't capture any errors.
    if (System.isBrowserView()) {
        Logger.console.debug("Logger client console.error is not wrapped to capture logs.");
        return;
    }
    Logger.console.debug("Logger client console.error is wrapped to capture logs.");
    // save console.error function for internal use since it will be wrapped below to send errors to Central Logger.
    const standardErrorFunction = globalThis.console.error.bind(globalThis.console);
    // make original error function available as console.unwrappedError for cases where the wrapped version needs to be bypassed
    globalThis.console.unwrappedError = globalThis.console.error;
    /**
     * wrap console.error so all error messages are routed to Central Logger before being logged locally.
     */
    globalThis.console.error = function (...args) {
        // annotate to identify source of message
        args.push("(console error)");
        let filteredArgs;
        try {
            // filter out any console args that cannot be later serialized when sending to Central Logger
            filteredArgs = JSON.parse(JSON.stringify(args));
        }
        catch (_a) {
            filteredArgs = "console.error: arguments could not be serialized for logging";
            args.push("arguments could not be serialized to send to Central Logger");
            standardErrorFunction(...args);
        }
        Logger.console.error(...filteredArgs);
    };
};
/**
 * Capture generic errors and send them to the Logger. This allows the central logger to report on unhandled exceptions and Promise rejects.
 * AddEventListener's useCapture parameter is set to true to ensure the listener is triggered early and will not be blocked.
 */
const maybeCatchUnhandledErrors = () => {
    if (Globals.addEventListener)
        Globals.addEventListener("error", (errorObject) => {
            // check if errorObject is an ErrorEvent
            if ((errorObject === null || errorObject === void 0 ? void 0 : errorObject.message) && (errorObject === null || errorObject === void 0 ? void 0 : errorObject.filename)) {
                Logger.console.error(`Logger client caught ErrorEvent. Error: ${errorObject.message}`, `File: ${errorObject.filename}`, `Line number: ${errorObject.lineno}`);
            }
            else {
                // Probably a DOM Event (as opposed to ErrorEvent); either way capture as much as possible but only use warning.
                // Note JSON.stringify(errorObject) essentially fails here so have to work around that.
                Logger.console.warn(`Logger client caught what is likely a DOM error event where type=${errorObject === null || errorObject === void 0 ? void 0 : errorObject.type} and target=${errorObject === null || errorObject === void 0 ? void 0 : errorObject.target}. Probably due to <img> or <script> failing to load.  See component's browserView window for more details.`);
                // Much of the Event data is not serializable so can't be sent to Central logger, so log details here using a standard console warning.
                globalThis.console.warn("Event Details (for above message)", errorObject);
            }
        }, true);
    if (Globals.addEventListener)
        Globals.addEventListener("unhandledrejection", (event) => {
            Logger.console.error("Logger client caught Unhandled rejection", "reason", 
            // This casting is needed, otherwise compiler loses track of what kind of event it is (probably a TSC version thing).
            event.reason, JSON.stringify(event));
        }, true);
};
/**
 * Sets up error handlers for unhandled errors, unhandled rejections, and console.error messages
 * and copies them to the central logger. If the window contents is a browser view, then console.error
 * messages are left unprocessed.
 */
export const unhandledErrors = () => {
    maybeCatchUnhandledErrors();
    maybeSendConsoleErrorsToCentralLogger();
};
//# sourceMappingURL=unhandledErrors.js.map