From 9c05e2c09327891ae0747e4060b49854753a2b64 Mon Sep 17 00:00:00 2001 From: Ldoppea Date: Fri, 31 May 2024 16:00:01 +0200 Subject: [PATCH] feat: Forward operation in `StackLink.request()` on Network error On the Flagship app we want to serve `.query()` request using the `StackLink` when the device is connected, but we want to fallback to the `PouchLink` when we detect a connection loss In previous commit we tried pro-actively detect for connexion loss by calling an `isOnline()` method before processing the request But we want to also catch network errors when the `isOnline()` methods fails to detect connection loss, then we also fallback to the next `Link` --- packages/cozy-client/src/StackLink.js | 14 +++++++++++--- packages/cozy-client/src/utils.js | 12 ++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/cozy-client/src/StackLink.js b/packages/cozy-client/src/StackLink.js index deaa22baf..038511a66 100644 --- a/packages/cozy-client/src/StackLink.js +++ b/packages/cozy-client/src/StackLink.js @@ -5,6 +5,7 @@ import CozyLink from './CozyLink' import { DOCTYPE_FILES } from './const' import { BulkEditError } from './errors' import logger from './logger' +import { isReactNativeOfflineError } from './utils' /** * @@ -84,10 +85,17 @@ export default class StackLink extends CozyLink { return forward(operation) } - if (operation.mutationType) { - return this.executeMutation(operation, result, forward) + try { + if (operation.mutationType) { + return await this.executeMutation(operation, result, forward) + } + return await this.executeQuery(operation) + } catch (err) { + if (isReactNativeOfflineError(err)) { + return forward(operation) + } + throw err } - return this.executeQuery(operation) } async persistData(data, forward) { diff --git a/packages/cozy-client/src/utils.js b/packages/cozy-client/src/utils.js index 973ac5cf3..8ac4fe55b 100644 --- a/packages/cozy-client/src/utils.js +++ b/packages/cozy-client/src/utils.js @@ -68,3 +68,15 @@ export const hasQueriesBeenLoaded = queriesResults => { hasQueryBeenLoaded(queryResult) ) } + +/** + * Check is the error is about ReactNative not having access to internet + * + * @param {Error} err - The error to check + * @returns {boolean} True if the error is a network error, otherwise false + */ +export const isReactNativeOfflineError = err => { + // This error message is specific to ReactNative + // Network errors on a browser would produce another error.message + return err.message === 'Network request failed' +}