mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
899fa25d38
Summary: We had some confusion lately, where errorName was used to dump "error message". This caused problems in Scuba. This doc should add some clarity on what is expected from endFailure users. Changelog: [Internal][Added] - Documentation for method in UserFlow.js class Reviewed By: mityal Differential Revision: D30192127 fbshipit-source-id: d057668aab714a9342131c83daf41cbe9372cb39
159 lines
4.4 KiB
JavaScript
159 lines
4.4 KiB
JavaScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @format
|
|
* @flow strict
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const AUTO_INSTANCE_KEY = -1;
|
|
|
|
export type FlowId = {
|
|
markerId: number,
|
|
instanceKey: number,
|
|
};
|
|
|
|
export type PointData = $Shape<{
|
|
string: ?{[string]: string, ...},
|
|
int: ?{[string]: number, ...},
|
|
double: ?{[string]: number, ...},
|
|
bool: ?{[string]: boolean, ...},
|
|
string_array: ?{[string]: $ReadOnlyArray<string>, ...},
|
|
int_array: ?{[string]: $ReadOnlyArray<number>, ...},
|
|
double_array: ?{[string]: $ReadOnlyArray<number>, ...},
|
|
bool_array: ?{[string]: $ReadOnlyArray<boolean>, ...},
|
|
}>;
|
|
|
|
/**
|
|
* API for tracking reliability of your user interactions
|
|
*
|
|
* Example:
|
|
* const flowId = UserFlow.newFlowId(QuickLogItentifiersExample.EXAMPLE_EVENT);
|
|
* ...
|
|
* UserFlow.start(flowId, {triggerSource: "user_click", cancelOnBackground: true});
|
|
* ...
|
|
* UserFlow.addAnnotation(flowId, "cached", "true");
|
|
* ...
|
|
* UserFlow.addPoint(flowId, "reload");
|
|
* ...
|
|
* UserFlow.endSuccess(flowId);
|
|
*/
|
|
const UserFlow = {
|
|
/**
|
|
* Creates FlowId from markerId and instanceKey.
|
|
* You will pass FlowId in every other method of UserFlow API.
|
|
*
|
|
* By default, instanceKey will generate unique instance every time you call userFlowGetId with markerId only.
|
|
*/
|
|
newFlowId(markerId: number, instanceKey: number = AUTO_INSTANCE_KEY): FlowId {
|
|
var resolvedInstanceKey = instanceKey;
|
|
if (instanceKey === AUTO_INSTANCE_KEY) {
|
|
if (global.nativeUserFlowNextInstanceKey) {
|
|
resolvedInstanceKey = global.nativeUserFlowNextInstanceKey(markerId);
|
|
} else {
|
|
// There is no JSI methods installed, API won't do anything
|
|
resolvedInstanceKey = 0;
|
|
}
|
|
}
|
|
return {
|
|
markerId: markerId,
|
|
instanceKey: resolvedInstanceKey,
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Starts new flow.
|
|
* Example:
|
|
* UserFlow.start(flowId, {triggerSource: 'user_click', cancelOnBackground: true})
|
|
*
|
|
* Specify triggerSource as a place where your flow has started.
|
|
* Specify if flow should be automatically cancelled if applicaton goes to background.
|
|
* It is recommended to use true for cancelOnBackground - this reduces amount of lost flows due to instrumentation mistakes.
|
|
* Only if you know that your flow should survive app backgrounding - use false. This includes cases of tracking cross application interactions.
|
|
*
|
|
*/
|
|
start(
|
|
flowId: FlowId,
|
|
options: {triggerSource: string, cancelOnBackground: boolean},
|
|
): void {
|
|
if (global.nativeUserFlowStart) {
|
|
global.nativeUserFlowStart(
|
|
flowId.markerId,
|
|
flowId.instanceKey,
|
|
options.triggerSource,
|
|
options.cancelOnBackground,
|
|
);
|
|
}
|
|
},
|
|
|
|
addAnnotation(
|
|
flowId: FlowId,
|
|
annotationName: string,
|
|
annotationValue: string | boolean,
|
|
): void {
|
|
if (global.nativeUserFlowAddAnnotation) {
|
|
global.nativeUserFlowAddAnnotation(
|
|
flowId.markerId,
|
|
flowId.instanceKey,
|
|
annotationName,
|
|
annotationValue,
|
|
);
|
|
}
|
|
},
|
|
|
|
addPoint(flowId: FlowId, pointName: string, data: ?PointData = null): void {
|
|
if (global.nativeUserFlowAddPoint) {
|
|
global.nativeUserFlowAddPoint(
|
|
flowId.markerId,
|
|
flowId.instanceKey,
|
|
pointName,
|
|
data,
|
|
);
|
|
}
|
|
},
|
|
|
|
endSuccess(flowId: FlowId): void {
|
|
if (global.nativeUserFlowEndSuccess) {
|
|
global.nativeUserFlowEndSuccess(flowId.markerId, flowId.instanceKey);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Completes flow as failed
|
|
*
|
|
* ErrorName should be short and easily categorazable (it is attached as point to the UserFlow and can be used for aggregations).
|
|
* For example: io_error, network_error, parse_error, validation_error.
|
|
* DebugInfo is free-form string, where you can attach detailed error message. It is attached as data to the point (see ErrorName).
|
|
*/
|
|
endFailure(
|
|
flowId: FlowId,
|
|
errorName: string,
|
|
debugInfo: ?string = null,
|
|
): void {
|
|
if (global.nativeUserFlowEndFail) {
|
|
global.nativeUserFlowEndFail(
|
|
flowId.markerId,
|
|
flowId.instanceKey,
|
|
errorName,
|
|
debugInfo,
|
|
);
|
|
}
|
|
},
|
|
|
|
endCancel(flowId: FlowId, cancelReason: string): void {
|
|
if (global.nativeUserFlowEndCancel) {
|
|
global.nativeUserFlowEndCancel(
|
|
flowId.markerId,
|
|
flowId.instanceKey,
|
|
cancelReason,
|
|
);
|
|
}
|
|
},
|
|
};
|
|
|
|
module.exports = UserFlow;
|