Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply Onyx failureData on fetch failure #27650

Merged
merged 12 commits into from
Oct 4, 2023
17 changes: 5 additions & 12 deletions src/libs/Middleware/SaveResponseInOnyx.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,12 @@ const requestsToIgnoreLastUpdateID = ['OpenApp', 'ReconnectApp', 'GetMissingOnyx
function SaveResponseInOnyx(requestResponse, request) {
return requestResponse.then((response) => {
// Make sure we have response data (i.e. response isn't a promise being passed down to us by a failed retry request and response undefined)
if (!response) {
if (!response && !request.successData && !request.failureData) {
luacmartins marked this conversation as resolved.
Show resolved Hide resolved
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should return Promise.resolve()` here to be consistent.

}
const onyxUpdates = response.onyxData;

// Sometimes we call requests that are successfull but they don't have any response or any success/failure data to set. Let's return early since
// we don't need to store anything here.
if (!onyxUpdates && !request.successData && !request.failureData) {
return Promise.resolve(response);
luacmartins marked this conversation as resolved.
Show resolved Hide resolved
}

// If there is an OnyxUpdate for using memory only keys, enable them
_.find(onyxUpdates, ({key, value}) => {
_.find(_.get(response, 'onyxData', {}), ({key, value}) => {
if (key !== ONYXKEYS.IS_USING_MEMORY_ONLY_KEYS || !value) {
return false;
}
Expand All @@ -39,13 +32,13 @@ function SaveResponseInOnyx(requestResponse, request) {

const responseToApply = {
type: CONST.ONYX_UPDATE_TYPES.HTTPS,
lastUpdateID: Number(response.lastUpdateID || 0),
previousUpdateID: Number(response.previousUpdateID || 0),
lastUpdateID: Number((response && response.lastUpdateID) || 0),
previousUpdateID: Number((response && response.previousUpdateID) || 0),
request,
response,
};

if (_.includes(requestsToIgnoreLastUpdateID, request.command) || !OnyxUpdates.doesClientNeedToBeUpdated(Number(response.previousUpdateID || 0))) {
if (_.includes(requestsToIgnoreLastUpdateID, request.command) || !OnyxUpdates.doesClientNeedToBeUpdated(Number((response && response.previousUpdateID) || 0))) {
return OnyxUpdates.apply(responseToApply);
}

Expand Down
10 changes: 5 additions & 5 deletions src/libs/actions/OnyxUpdates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Onyx.connect({
callback: (val) => (lastUpdateIDAppliedToClient = val),
});

function applyHTTPSOnyxUpdates(request: Request, response: Response) {
function applyHTTPSOnyxUpdates(request: Request, response: Response | undefined) {
console.debug('[OnyxUpdateManager] Applying https update');
// For most requests we can immediately update Onyx. For write requests we queue the updates and apply them after the sequential queue has flushed to prevent a replay effect in
// the UI. See https://github.com/Expensify/App/issues/12775 for more info.
Expand All @@ -24,15 +24,15 @@ function applyHTTPSOnyxUpdates(request: Request, response: Response) {
// First apply any onyx data updates that are being sent back from the API. We wait for this to complete and then
// apply successData or failureData. This ensures that we do not update any pending, loading, or other UI states contained
// in successData/failureData until after the component has received and API data.
const onyxDataUpdatePromise = response.onyxData ? updateHandler(response.onyxData) : Promise.resolve();
const onyxDataUpdatePromise = response?.onyxData ? updateHandler(response?.onyxData) : Promise.resolve();

return onyxDataUpdatePromise
.then(() => {
// Handle the request's success/failure data (client-side data)
if (response.jsonCode === 200 && request.successData) {
if (response?.jsonCode === 200 && request.successData) {
return updateHandler(request.successData);
}
if (response.jsonCode !== 200 && request.failureData) {
if (response?.jsonCode !== 200 && request.failureData) {
return updateHandler(request.failureData);
}
return Promise.resolve();
Expand Down Expand Up @@ -68,7 +68,7 @@ function apply({lastUpdateID, type, request, response, updates}: OnyxUpdatesFrom
if (lastUpdateID && (lastUpdateIDAppliedToClient === null || Number(lastUpdateID) > lastUpdateIDAppliedToClient)) {
Onyx.merge(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, Number(lastUpdateID));
}
if (type === CONST.ONYX_UPDATE_TYPES.HTTPS && request && response) {
if (type === CONST.ONYX_UPDATE_TYPES.HTTPS && request) {
return applyHTTPSOnyxUpdates(request, response);
}
if (type === CONST.ONYX_UPDATE_TYPES.PUSHER && updates) {
Expand Down
Loading