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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import Sentry from "@sentry/node"; import KEYMAN_VERSION from "@keymanapp/keyman-version"; import { getOption } from "./options.js"; export type SentryNodeOptions = Sentry.NodeOptions; /** * Maximum delay on shutdown of process to send pending events * to Sentry, in msec */ const CLOSE_TIMEOUT = 2000; let isInit = false; export class KeymanSentry { static isEnabled() { if(process.argv.includes('--no-error-reporting')) { return false; } if(process.argv.includes('--error-reporting')) { return true; } return getOption('automatically report errors', true); } static init(options?: SentryNodeOptions) { options = options ?? {}; Sentry.init({ ...options, dsn: 'https://39b25a09410349a58fe12aaf721565af@o1005580.ingest.sentry.io/5983519', // Keyman Developer environment: KEYMAN_VERSION.VERSION_ENVIRONMENT, release: KEYMAN_VERSION.VERSION_GIT_TAG, }); isInit = true; } private static writeSentryMessage(eventId: string) { process.stderr.write(` This error has been automatically reported to the Keyman team. Identifier: ${eventId} Application: Keyman Developer Reported at: https://sentry.io/organizations/keyman/projects/keyman-developer/events/${eventId}/ `); } static async reportException(e: any, silent: boolean = true) { if(isInit) { const eventId = await Sentry.captureException(e); if(!silent) { this.writeSentryMessage(eventId); } return eventId; } return null; } static captureMessage(message: string) { if(isInit) { return Sentry.captureMessage(message); } else { return null; } } /** * capture an exception for Sentry; note that in local environments, this will normally * throw the exception rather than sending to Sentry * @param e * @param force if true, reports to Sentry even in local environments */ static async captureException(e: any, force?: boolean): Promise<never> { if(isInit) { // For local development, we don't want to bury the trace; we need the cast to avoid // TS2367 (comparison appears to be unintentional) if(!force && (KEYMAN_VERSION.VERSION_ENVIRONMENT as string) == 'local') { throw e; } const eventId = Sentry.captureException(e); process.stderr.write(` Fatal error: ${(e??'').toString()} `); this.writeSentryMessage(eventId); await this.close(); process.exit(1); } else { throw e; } } static async close() { if(isInit) { try { await Sentry.close(CLOSE_TIMEOUT); } catch(e) { // ignore any errors here } } } } |