Skip to content

Commit

Permalink
Handle http errors more gracefully
Browse files Browse the repository at this point in the history
  • Loading branch information
ericnewcomer committed Nov 8, 2024
1 parent 19a422a commit 1be188b
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 78 deletions.
33 changes: 19 additions & 14 deletions src/components/revisions/RevisionExplorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { renderIf } from 'utils';
import styles from './RevisionExplorer.module.scss';
import i18n from 'config/i18n';
import { PopTabType } from 'config/interfaces';
import { showError } from 'index';

const cx: any = classNames.bind(styles);

Expand Down Expand Up @@ -71,16 +72,16 @@ export class RevisionExplorer extends React.Component<
public handleUpdateRevisions(): Promise<void> {
if (this.props.assetStore !== null) {
const assets = this.props.assetStore.revisions;
return getAssets(
assets.endpoint + '?version=' + SPEC_VERSION,
assets.type,
assets.id || 'id'
).then((remoteAssets: Asset[]) => {
if (remoteAssets.length > 0) {
remoteAssets[0].content.current = true;
}
this.setState({ revisions: remoteAssets });
});
return getAssets(assets.endpoint + '?version=' + SPEC_VERSION, assets.type, assets.id || 'id')
.then((remoteAssets: Asset[]) => {
if (remoteAssets.length > 0) {
remoteAssets[0].content.current = true;
}
this.setState({ revisions: remoteAssets });
})
.catch(error => {
showError();
});
}
}

Expand Down Expand Up @@ -114,10 +115,14 @@ export class RevisionExplorer extends React.Component<
return (event: React.MouseEvent<HTMLDivElement>) => {
event.stopPropagation();
event.preventDefault();
getFlowDetails(this.props.assetStore.revisions, revision.id).then((details: FlowDetails) => {
this.props.loadFlowDefinition(details, this.props.assetStore);
this.setState({ revision });
});
getFlowDetails(this.props.assetStore.revisions, revision.id)
.then((details: FlowDetails) => {
this.props.loadFlowDefinition(details, this.props.assetStore);
this.setState({ revision });
})
.catch(error => {
showError();
});
};
};

Expand Down
11 changes: 10 additions & 1 deletion src/components/simulator/Simulator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { createUUID } from 'utils';
import { PopTabType } from 'config/interfaces';
import i18n from 'config/i18n';
import { PopTab } from 'components/poptab/PopTab';
import { showError } from 'index';

export const SIMULATOR_CONTACT_UUID = 'fb3787ab-2eda-48a0-a2bc-e2ddadec1286';
const SIMULATOR_CONTACT_URNS = ['tel:+12065551212'];
Expand Down Expand Up @@ -486,7 +487,15 @@ export class Simulator extends React.Component<SimulatorProps, SimulatorState> {
axios.default
.post(getURL(this.context.config.endpoints.simulateStart), JSON.stringify(body, null, 2))
.then((response: axios.AxiosResponse) => {
this.updateRunContext(response.data as RunContext);
if (
response.headers['content-type'] === 'application/json' &&
response.status >= 200 &&
response.status < 300
) {
this.updateRunContext(response.data as RunContext);
} else {
showError();
}
});
}
);
Expand Down
43 changes: 34 additions & 9 deletions src/external/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,17 @@ export const getActivity = (
new Promise<Activity>((resolve, reject) =>
axios
.get(`${activityEndpoint}?flow=${flowUUID}`, { headers })
.then((response: AxiosResponse) => resolve(response.data as Activity))
.then((response: AxiosResponse) => {
if (
response.headers['content-type'] === 'application/json' &&
response.status >= 200 &&
response.status < 300
) {
resolve(response.data as Activity);
return;
}
reject(response);
})
.catch((error: any) => reject(error))
);

Expand Down Expand Up @@ -139,12 +149,20 @@ export const getAssetPage = (url: string, type: AssetType, id: string): Promise<
axios
.get(url)
.then((response: AxiosResponse) => {
const assets: Asset[] = response.data.results.map((result: any, idx: number) => {
const asset = resultToAsset(result, type, id);
asset.order = idx;
return asset;
});
resolve({ assets, next: response.data.next });
if (
response.headers['content-type'] === 'application/json' &&
response.status >= 200 &&
response.status < 300
) {
const assets: Asset[] = response.data.results.map((result: any, idx: number) => {
const asset = resultToAsset(result, type, id);
asset.order = idx;
return asset;
});
resolve({ assets, next: response.data.next });
return;
}
reject(response);
})
.catch(error => reject(error));
});
Expand Down Expand Up @@ -392,8 +410,15 @@ export const getFlowDetails = (revisions: Assets, id: string = null): Promise<Fl
axios
.get(url)
.then((response: AxiosResponse) => {
const details = response.data as FlowDetails;
return resolve(details);
if (
response.headers['content-type'] === 'application/json' &&
response.status >= 200 &&
response.status < 300
) {
const details = response.data as FlowDetails;
return resolve(details);
}
return reject(response);
})
.catch(error => reject(error));
} else {
Expand Down
8 changes: 8 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,11 @@ document.dispatchEvent(new CustomEvent('temba-floweditor-loaded'));
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

export const showError = (error = null) => {
if (window.showErrorDialog) {
window.showErrorDialog(error);
} else {
console.log.error(error);
}
};
42 changes: 23 additions & 19 deletions src/store/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -683,29 +683,33 @@ export const fetchFlowActivity = (
} = getState();

if (visible) {
getActivity(endpoint, uuid).then((activity: Activity) => {
// every interval we back off a bit up to 5 minutes
if (activity) {
const updates: Partial<EditorState> = {
liveActivity: activity,
activityInterval: Math.min(60000 * 5, activityInterval + 200)
};
getActivity(endpoint, uuid)
.then((activity: Activity) => {
// every interval we back off a bit up to 5 minutes
if (activity) {
const updates: Partial<EditorState> = {
liveActivity: activity,
activityInterval: Math.min(60000 * 5, activityInterval + 200)
};

if (!simulating) {
updates.activity = activity;
}
if (!simulating) {
updates.activity = activity;
}

dispatch(mergeEditorState(updates));
dispatch(mergeEditorState(updates));

if (activityTimeout) {
window.clearTimeout(activityTimeout);
}
if (activityTimeout) {
window.clearTimeout(activityTimeout);
}

activityTimeout = window.setTimeout(() => {
fetchFlowActivity(endpoint, dispatch, getState, uuid);
}, activityInterval);
}
});
activityTimeout = window.setTimeout(() => {
fetchFlowActivity(endpoint, dispatch, getState, uuid);
}, activityInterval);
}
})
.catch(() => {
// failure fetching activity, if this happens we stop trying to fetch more
});
} else {
if (activityTimeout) {
window.clearTimeout(activityTimeout);
Expand Down
83 changes: 48 additions & 35 deletions src/store/thunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,53 +238,66 @@ export const createDirty = (

lastDirtyAttemptTimeout = window.setTimeout(() => {
postingRevision = true;
saveRevision(revisionsEndpoint, newDefinition).then(
(result: SaveResult) => {
const revision = result.revision;
definition.revision = revision.revision;
dispatch(updateDefinition(definition));
dispatch(updateIssues(createFlowIssueMap(issues, result.issues)));

if (result.metadata) {
dispatch(updateMetadata(result.metadata));
}

const updatedAssets = mutators.addRevision(assetStore, revision);
dispatch(updateAssets(updatedAssets));
dispatch(
mergeEditorState({
currentRevision: revision.revision,
saving: false,
activityInterval: ACTIVITY_INTERVAL
})
);
saveRevision(revisionsEndpoint, newDefinition)
.then(
(result: SaveResult) => {
const revision = result.revision;
definition.revision = revision.revision;
dispatch(updateDefinition(definition));
dispatch(updateIssues(createFlowIssueMap(issues, result.issues)));

if (result.metadata) {
dispatch(updateMetadata(result.metadata));
}

lastSuccessfulMillis = new Date().getTime();
postingRevision = false;
},
(error: AxiosError) => {
let body = NETWORK_ERROR;
const updatedAssets = mutators.addRevision(assetStore, revision);
dispatch(updateAssets(updatedAssets));
dispatch(
mergeEditorState({
currentRevision: revision.revision,
saving: false,
activityInterval: ACTIVITY_INTERVAL
})
);

lastSuccessfulMillis = new Date().getTime();
postingRevision = false;
},
(error: AxiosError) => {
let body = NETWORK_ERROR;

if (error.response && error.response.status === 500) {
body = SERVER_ERROR;
}

if (error.response && error.response.status === 500) {
body = SERVER_ERROR;
}
if (error.response && error.response.data && error.response.data.description) {
body = error.response.data.description;
}

if (error.response && error.response.data && error.response.data.description) {
body = error.response.data.description;
dispatch(
mergeEditorState({
modalMessage: {
title: "Uh oh, we couldn't save your changes",
body
},
saving: false
})
);
postingRevision = false;
}

)
.catch(() => {
dispatch(
mergeEditorState({
modalMessage: {
title: "Uh oh, we couldn't save your changes",
body
title: 'Uh oh',
body: "We couldn't save your changes, please try again or refresh the page."
},
saving: false
})
);
postingRevision = false;
}
);
});
}, quiet);
};

Expand Down

0 comments on commit 1be188b

Please sign in to comment.