/** * Copyright 2018-present Facebook. * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * @format */ import {getInstance} from '../fb-stubs/Logger'; export class UnsupportedError extends Error { constructor(message: string) { super(message); } } /* * Wraps a Promise, preserving it's functionality but logging the success or failure state of it, with a given name, based on whether it's fulfilled or rejected. Use this variant to report failures in core platform (Flipper) code. */ export function reportPlatformFailures( promise: Promise, name: string, ): Promise { return promise.then( fulfilledValue => { logPlatformSuccessRate(name, {isSuccess: true}); return fulfilledValue; }, rejectionReason => { logPlatformSuccessRate(name, { isSuccess: false, supportedOperation: !(rejectionReason instanceof UnsupportedError), error: rejectionReason, }); return Promise.reject(rejectionReason); }, ); } /* * Wraps a Promise, preserving it's functionality but logging the success or failure state of it, with a given name, based on whether it's fulfilled or rejected. Use this variant to report failures in plugin code. */ export function reportPluginFailures( promise: Promise, name: string, plugin: string, ): Promise { return promise.then( fulfilledValue => { logPluginSuccessRate(name, plugin, {isSuccess: true}); return fulfilledValue; }, rejectionReason => { logPluginSuccessRate(name, plugin, { isSuccess: false, supportedOperation: !(rejectionReason instanceof UnsupportedError), error: rejectionReason, }); return Promise.reject(rejectionReason); }, ); } /* * Wraps a closure, preserving it's functionality but logging the success or failure state of it. */ export function tryCatchReportPlatformFailures( closure: () => T, name: string, ): T { try { const result = closure(); logPlatformSuccessRate(name, {isSuccess: true}); return result; } catch (e) { logPlatformSuccessRate(name, { isSuccess: false, supportedOperation: !(e instanceof UnsupportedError), error: e, }); throw e; } } type Result = | {isSuccess: true} | {isSuccess: false, supportedOperation: boolean, error: any}; function logPlatformSuccessRate(name: string, result: Result) { if (result.isSuccess) { getInstance().track('success-rate', name, {value: 1}); } else { getInstance().track('success-rate', name, { value: 0, supportedOperation: result.supportedOperation ? 1 : 0, error: extractMessage(result.error), }); } } function logPluginSuccessRate(name: string, plugin: string, result: Result) { if (result.isSuccess) { getInstance().track('success-rate', name, {value: 1}, plugin); } else { getInstance().track( 'success-rate', name, { value: 0, supportedOperation: result.supportedOperation ? 1 : 0, error: extractMessage(result.error), }, plugin, ); } } function extractMessage(error: any) { if (error instanceof Error) { return error.message; } return JSON.stringify(error); }