Skip to content

Commit

Permalink
Generate a report for thread push/poll inconsistency
Browse files Browse the repository at this point in the history
  • Loading branch information
Ashoat committed Jun 26, 2018
1 parent 50635c8 commit e3644a2
Show file tree
Hide file tree
Showing 14 changed files with 177 additions and 124 deletions.
24 changes: 12 additions & 12 deletions lib/actions/report-actions.js
Expand Up @@ -2,29 +2,29 @@

import type { FetchJSON } from '../utils/fetch-json';
import type {
ErrorReportCreationRequest,
ErrorReportCreationResponse,
ReportCreationRequest,
ReportCreationResponse,
} from '../types/report-types';

const sendErrorReportActionTypes = Object.freeze({
started: "SEND_ERROR_REPORT_STARTED",
success: "SEND_ERROR_REPORT_SUCCESS",
failed: "SEND_ERROR_REPORT_FAILED",
const sendReportActionTypes = Object.freeze({
started: "SEND_REPORT_STARTED",
success: "SEND_REPORT_SUCCESS",
failed: "SEND_REPORT_FAILED",
});
const fetchJSONOptions = { timeout: 60000 };
async function sendErrorReport(
async function sendReport(
fetchJSON: FetchJSON,
request: ErrorReportCreationRequest,
): Promise<ErrorReportCreationResponse> {
request: ReportCreationRequest,
): Promise<ReportCreationResponse> {
const response = await fetchJSON(
'create_error_report',
'create_report',
request,
fetchJSONOptions,
);
return { id: response.id };
}

export {
sendErrorReportActionTypes,
sendErrorReport,
sendReportActionTypes,
sendReport,
};
2 changes: 2 additions & 0 deletions lib/reducers/thread-reducer.js
Expand Up @@ -34,6 +34,7 @@ import {
pingActionTypes,
updateActivityActionTypes,
} from '../actions/ping-actions';
import { getConfig } from '../utils/config';

function pingPoll(
threadInfos: {[id: string]: RawThreadInfo},
Expand Down Expand Up @@ -184,6 +185,7 @@ function findInconsistencies(
}
return [{
type: serverRequestTypes.THREAD_POLL_PUSH_INCONSISTENCY,
platformDetails: getConfig().platformDetails,
beforeAction,
action,
pollResult,
Expand Down
1 change: 1 addition & 0 deletions lib/types/endpoints.js
Expand Up @@ -33,5 +33,6 @@ export const endpoint = Object.freeze({
CREATE_ERROR_REPORT: 'create_error_report',
FETCH_ERROR_REPORT_INFOS: 'fetch_error_report_infos',
REQUEST_ACCESS: 'request_access',
CREATE_REPORT: 'create_report',
});
export type Endpoint = $Values<typeof endpoint>;
10 changes: 5 additions & 5 deletions lib/types/redux-types.js
Expand Up @@ -46,7 +46,7 @@ import type {
} from './message-types';
import type { SetCookiePayload } from '../utils/action-utils';
import type { UpdateActivityResult } from './activity-types';
import type { ErrorReportCreationResponse } from './report-types';
import type { ReportCreationResponse } from './report-types';
import type { ServerRequest } from './request-types';
import type {
CalendarFilter,
Expand Down Expand Up @@ -498,16 +498,16 @@ export type BaseAction =
type: "HANDLE_VERIFICATION_CODE_SUCCESS",
loadingInfo: LoadingInfo,
|} | {|
type: "SEND_ERROR_REPORT_STARTED",
type: "SEND_REPORT_STARTED",
loadingInfo: LoadingInfo,
|} | {|
type: "SEND_ERROR_REPORT_FAILED",
type: "SEND_REPORT_FAILED",
error: true,
payload: Error,
loadingInfo: LoadingInfo,
|} | {|
type: "SEND_ERROR_REPORT_SUCCESS",
payload: ErrorReportCreationResponse,
type: "SEND_REPORT_SUCCESS",
payload: ReportCreationResponse,
loadingInfo: LoadingInfo,
|} | {|
type: "SET_URL_PREFIX",
Expand Down
54 changes: 36 additions & 18 deletions lib/types/report-types.js
Expand Up @@ -2,7 +2,24 @@

import type { BaseAppState, BaseAction } from './redux-types';
import type { UserInfo } from './user-types';
import type { DeviceType } from './device-types';
import type { PlatformDetails } from './device-types';
import type { RawThreadInfo } from './thread-types';

import invariant from 'invariant';

export const reportTypes = Object.freeze({
ERROR: 0,
THREAD_POLL_PUSH_INCONSISTENCY: 1,
});
type ReportType = $Values<typeof reportTypes>;
function assertReportType(reportType: number): ReportType {
invariant(
reportType === 0 ||
reportType === 1,
"number is not ReportType enum",
);
return reportType;
}

export type ErrorInfo = { componentStack: string };
export type ErrorData = {| error: Error, info?: ErrorInfo |};
Expand All @@ -11,45 +28,46 @@ export type FlatErrorData = {|
componentStack?: ?string,
|};

export type ErrorReportCreationRequest = {|
deviceType: DeviceType,
type ErrorReportCreationRequest = {|
type: 0,
platformDetails: PlatformDetails,
errors: $ReadOnlyArray<FlatErrorData>,
preloadedState: BaseAppState<*>,
currentState: BaseAppState<*>,
actions: $ReadOnlyArray<BaseAction>,
codeVersion: number,
stateVersion: number,
|};
type ThreadPollPushInconsistencyReportCreationRequest = {|
type: 1,
platformDetails: PlatformDetails,
beforeAction: {[id: string]: RawThreadInfo},
action: BaseAction,
pollResult: {[id: string]: RawThreadInfo},
pushResult: {[id: string]: RawThreadInfo},
|};
export type ReportCreationRequest =
| ErrorReportCreationRequest
| ThreadPollPushInconsistencyReportCreationRequest;

export type ErrorReportCreationResponse = {|
export type ReportCreationResponse = {|
id: string,
|};

export type ErrorReportInfo = {|
type ReportInfo = {|
id: string,
viewerID: string,
deviceType: DeviceType,
platformDetails: PlatformDetails,
creationTime: number,
codeVersion: number,
stateVersion: number,
|};

export type FetchErrorReportInfosRequest = {|
cursor: ?string,
|};

export type FetchErrorReportInfosResponse = {|
reports: $ReadOnlyArray<ErrorReportInfo>,
reports: $ReadOnlyArray<ReportInfo>,
userInfos: $ReadOnlyArray<UserInfo>,
|};

export type ErrorReport = {|
...ErrorReportCreationRequest,
viewerID: string,
creationTime: number,
id: string,
|};

export type ReduxToolsImport = {|
preloadedState: BaseAppState<*>,
payload: $ReadOnlyArray<BaseAction>,
Expand Down
3 changes: 2 additions & 1 deletion lib/types/request-types.js
@@ -1,6 +1,6 @@
// @flow

import type { Platform } from './device-types';
import type { Platform, PlatformDetails } from './device-types';
import type { RawThreadInfo } from './thread-types';
import type { BaseAction } from './redux-types';

Expand Down Expand Up @@ -45,6 +45,7 @@ type DeviceTokenClientResponse = {|

export type ThreadPollPushInconsistencyClientResponse = {|
type: 2,
platformDetails: PlatformDetails,
beforeAction: {[id: string]: RawThreadInfo},
action: BaseAction,
pollResult: {[id: string]: RawThreadInfo},
Expand Down
35 changes: 18 additions & 17 deletions native/crash.react.js
@@ -1,8 +1,9 @@
// @flow

import type {
ErrorReportCreationRequest,
ErrorReportCreationResponse,
import {
type ReportCreationRequest,
type ReportCreationResponse,
reportTypes,
} from 'lib/types/report-types';
import type { DispatchActionPromise } from 'lib/utils/action-utils';
import type { AppState } from './redux-setup';
Expand All @@ -25,10 +26,7 @@ import PropTypes from 'prop-types';
import invariant from 'invariant';

import { connect } from 'lib/utils/redux-utils';
import {
sendErrorReportActionTypes,
sendErrorReport,
} from 'lib/actions/report-actions';
import { sendReportActionTypes, sendReport } from 'lib/actions/report-actions';
import sleep from 'lib/utils/sleep';

import Button from './components/button.react';
Expand All @@ -46,9 +44,9 @@ type Props = {
// Redux dispatch functions
dispatchActionPromise: DispatchActionPromise,
// async functions that hit server APIs
sendErrorReport: (
request: ErrorReportCreationRequest,
) => Promise<ErrorReportCreationResponse>,
sendReport: (
request: ReportCreationRequest,
) => Promise<ReportCreationResponse>,
};
type State = {|
errorReportID: ?string,
Expand All @@ -64,7 +62,7 @@ class Crash extends React.PureComponent<Props, State> {
}),
})).isRequired,
dispatchActionPromise: PropTypes.func.isRequired,
sendErrorReport: PropTypes.func.isRequired,
sendReport: PropTypes.func.isRequired,
};
errorTitle = _shuffle(errorTitles)[0];
state = {
Expand All @@ -74,7 +72,7 @@ class Crash extends React.PureComponent<Props, State> {

componentDidMount() {
this.props.dispatchActionPromise(
sendErrorReportActionTypes,
sendReportActionTypes,
this.sendReport(),
);
this.timeOut();
Expand Down Expand Up @@ -144,17 +142,20 @@ class Crash extends React.PureComponent<Props, State> {
}

async sendReport() {
const result = await this.props.sendErrorReport({
deviceType: Platform.OS,
const result = await this.props.sendReport({
type: reportTypes.ERROR,
platformDetails: {
platform: Platform.OS,
codeVersion,
stateVersion: persistConfig.version,
},
errors: this.props.errorData.map(data => ({
errorMessage: data.error.message,
componentStack: data.info && data.info.componentStack,
})),
preloadedState: reduxLogger.preloadedState,
currentState: store.getState(),
actions: reduxLogger.actions,
codeVersion,
stateVersion: persistConfig.version,
});
this.setState({
errorReportID: result.id,
Expand Down Expand Up @@ -252,5 +253,5 @@ const styles = StyleSheet.create({

export default connect(
undefined,
{ sendErrorReport },
{ sendReport },
)(Crash);
33 changes: 0 additions & 33 deletions server/src/creators/error-report-creator.js

This file was deleted.

8 changes: 5 additions & 3 deletions server/src/fetchers/report-fetchers.js
Expand Up @@ -38,10 +38,12 @@ async function fetchErrorReportInfos(
reports.push({
id: row.id.toString(),
viewerID,
deviceType: row.platform,
platformDetails: {
platform: row.platform,
codeVersion: row.report.codeVersion,
stateVersion: row.report.stateVersion,
},
creationTime: row.creation_time,
codeVersion: row.report.codeVersion,
stateVersion: row.report.stateVersion,
});
if (row.username) {
userInfos[viewerID] = {
Expand Down
24 changes: 22 additions & 2 deletions server/src/responders/ping-responders.js
Expand Up @@ -3,8 +3,12 @@
import type { PingRequest, PingResponse } from 'lib/types/ping-types';
import { defaultNumberPerThread } from 'lib/types/message-types';
import type { Viewer } from '../session/viewer';
import { serverRequestTypes } from 'lib/types/request-types';
import {
serverRequestTypes,
type ThreadPollPushInconsistencyClientResponse,
} from 'lib/types/request-types';
import { isDeviceType, assertDeviceType } from 'lib/types/device-types';
import { reportTypes } from 'lib/types/report-types';

import t from 'tcomb';
import invariant from 'invariant';
Expand All @@ -27,6 +31,7 @@ import { fetchCurrentUserInfo } from '../fetchers/user-fetchers';
import { fetchUpdateInfos } from '../fetchers/update-fetchers';
import { recordDeliveredUpdate, setCookiePlatform } from '../session/cookies';
import { deviceTokenUpdater } from '../updaters/device-token-updaters';
import createReport from '../creators/report-creator';

const pingRequestInputValidator = tShape({
calendarQuery: entryQueryInputValidator,
Expand Down Expand Up @@ -109,7 +114,10 @@ async function pingResponder(
clientResponse.type ===
serverRequestTypes.THREAD_POLL_PUSH_INCONSISTENCY
) {
// TODO record here
clientResponsePromises.push(recordThreadPollPushInconsistency(
viewer,
clientResponse,
));
}
}
}
Expand Down Expand Up @@ -196,6 +204,18 @@ async function pingResponder(
return response;
}

async function recordThreadPollPushInconsistency(
viewer: Viewer,
response: ThreadPollPushInconsistencyClientResponse,
): Promise<void> {
const { type, ...rest } = response;
const reportCreationRequest = {
...rest,
type: reportTypes.THREAD_POLL_PUSH_INCONSISTENCY,
};
await createReport(viewer, reportCreationRequest);
}

export {
pingResponder,
};

0 comments on commit e3644a2

Please sign in to comment.