Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 1x 3x 4x 4x 4x 4x 2x 2x 2x 4x 4x 4x 1x 1x 5x 1x 4x 4x 4x 4x | import { recordCrash } from "./crashLog";
// Installe les capteurs globaux d'erreurs JS. A appeler UNE seule fois, le plus
// tot possible (au chargement du module App), avant tout rendu. Voir
// OBSERVABILITE_CRASH.md (approche A, ยง3). Zero dependance externe.
type GlobalErrorHandler = (error: unknown, isFatal?: boolean) => void;
type ErrorUtilsLike = {
getGlobalHandler?: () => GlobalErrorHandler | undefined;
setGlobalHandler?: (handler: GlobalErrorHandler) => void;
};
let installed = false;
function toError(value: unknown): Error {
return value instanceof Error ? value : new Error(String(value));
}
function installGlobalErrorHandler(): void {
const errorUtils = (globalThis as unknown as { ErrorUtils?: ErrorUtilsLike }).ErrorUtils;
Iif (!errorUtils?.setGlobalHandler) {
return;
}
// On CHAINE le handler precedent : on ne casse ni l'ecran rouge de dev ni le
// comportement de crash natif en prod, on ne fait que journaliser au passage.
const previous = errorUtils.getGlobalHandler?.();
errorUtils.setGlobalHandler((error, isFatal) => {
const err = toError(error);
void recordCrash({ kind: "fatal", message: err.message, stack: err.stack, isFatal });
previous?.(error, isFatal);
});
}
function installRejectionTracking(): void {
// Best-effort : le suivi des rejets de promesse non geres depend du polyfill
// "promise" embarque par React Native. Absent dans certains environnements
// (ex. Jest) -> on ignore, les exceptions fatales restent captees.
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const tracking = require("promise/setimmediate/rejection-tracking") as {
enable: (options: {
allRejections?: boolean;
onUnhandled?: (id: number, error: unknown) => void;
onHandled?: (id: number) => void;
}) => void;
};
tracking.enable({
allRejections: true,
onUnhandled: (_id, error) => {
const err = toError(error);
void recordCrash({ kind: "rejection", message: err.message, stack: err.stack });
},
onHandled: () => {},
});
} catch {
// Module indisponible : suivi des rejets non installe (sans incidence sur le reste).
}
}
export function installCrashHandlers(): void {
if (installed) {
return;
}
installed = true;
installGlobalErrorHandler();
installRejectionTracking();
}
// Reservoir de test uniquement : permet de reinstaller les handlers entre tests.
export function __resetCrashHandlersForTests(): void {
installed = false;
}
|