diff --git a/src/fb-interfaces/Logger.js b/src/fb-interfaces/Logger.js index e255bbd30..1f25f3568 100644 --- a/src/fb-interfaces/Logger.js +++ b/src/fb-interfaces/Logger.js @@ -6,7 +6,12 @@ */ export type LogTypes = 'error' | 'warn' | 'info' | 'debug'; -export type TrackType = 'duration' | 'usage' | 'performance' | 'success-rate'; +export type TrackType = + | 'duration' + | 'usage' + | 'performance' + | 'success-rate' + | 'operation-cancelled'; export interface Logger { track(type: TrackType, event: string, data: ?any, plugin?: string): void; diff --git a/src/utils/Idler.js b/src/utils/Idler.js index fbfe0a1e7..772ab68ef 100644 --- a/src/utils/Idler.js +++ b/src/utils/Idler.js @@ -4,6 +4,9 @@ * LICENSE file in the root directory of this source tree. * @format */ + +import {CancelledPromiseError} from './errors.tsx'; + export class Idler { lastIdle: number; interval: number; @@ -17,7 +20,7 @@ export class Idler { idle(): Promise { if (this.kill) { - throw new Error('Idler got killed'); + throw new CancelledPromiseError('Idler got killed'); } const now = performance.now(); if (now - this.lastIdle > this.interval) { diff --git a/src/utils/errors.tsx b/src/utils/errors.tsx index b01db4f23..e6bca67c3 100644 --- a/src/utils/errors.tsx +++ b/src/utils/errors.tsx @@ -5,6 +5,12 @@ * @format */ +export class CancelledPromiseError extends Error { + constructor(msg: string) { + super(msg); + this.name = 'CancelledPromiseError'; + } +} export function getStringFromErrorLike(e: any) { if (typeof e == 'string') { return e; diff --git a/src/utils/metrics.js b/src/utils/metrics.js index 4b558ca13..e8d6d81f4 100644 --- a/src/utils/metrics.js +++ b/src/utils/metrics.js @@ -6,6 +6,7 @@ */ import {getInstance} from '../fb-stubs/Logger.tsx'; +import {CancelledPromiseError} from './errors.tsx'; export class UnsupportedError extends Error { constructor(message: string) { @@ -30,11 +31,17 @@ export function reportPlatformFailures( return fulfilledValue; }, rejectionReason => { - logPlatformSuccessRate(name, { - isSuccess: false, - supportedOperation: !(rejectionReason instanceof UnsupportedError), - error: rejectionReason, - }); + if (rejectionReason instanceof CancelledPromiseError) { + logPlatformSuccessRate(name, { + isCancelled: true, + }); + } else { + logPlatformSuccessRate(name, { + isSuccess: false, + supportedOperation: !(rejectionReason instanceof UnsupportedError), + error: rejectionReason, + }); + } return Promise.reject(rejectionReason); }, ); @@ -58,11 +65,17 @@ export function reportPluginFailures( return fulfilledValue; }, rejectionReason => { - logPluginSuccessRate(name, plugin, { - isSuccess: false, - supportedOperation: !(rejectionReason instanceof UnsupportedError), - error: rejectionReason, - }); + if (rejectionReason instanceof CancelledPromiseError) { + logPluginSuccessRate(name, plugin, { + isCancelled: true, + }); + } else { + logPluginSuccessRate(name, plugin, { + isSuccess: false, + supportedOperation: !(rejectionReason instanceof UnsupportedError), + error: rejectionReason, + }); + } return Promise.reject(rejectionReason); }, ); @@ -92,11 +105,14 @@ export function tryCatchReportPlatformFailures( type Result = | {isSuccess: true} + | {isCancelled: true} | {isSuccess: false, supportedOperation: boolean, error: any}; function logPlatformSuccessRate(name: string, result: Result) { if (result.isSuccess) { getInstance().track('success-rate', name, {value: 1}); + } else if (result.isCancelled) { + getInstance().track('operation-cancelled', name); } else { getInstance().track('success-rate', name, { value: 0, @@ -109,6 +125,8 @@ function logPlatformSuccessRate(name: string, result: Result) { function logPluginSuccessRate(name: string, plugin: string, result: Result) { if (result.isSuccess) { getInstance().track('success-rate', name, {value: 1}, plugin); + } else if (result.isCancelled) { + getInstance().track('operation-cancelled', name, undefined, plugin); } else { getInstance().track( 'success-rate',