I have a login page in React-Native. It works fine if I have an Internet connection, but I now want to handle the case where Internet (or the server) is down. The way I want to do this is using timeouts: the app should try to connect, and if there is no success in five seconds, I want to print an error message.
I have done this using the following code, taken from here:
export function timeout(
promise,
message = 'Request timeout',
timeout = DEFAULT_TIMEOUT,
) {
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
console.log('timeout called');
reject(new Error(message));
}, timeout);
promise.then(
response => {
clearTimeout(timeoutId);
resolve(response);
},
err => {
console.log('timeout NOT called');
clearTimeout(timeoutId);
reject(err);
},
);
});
}
From the login page, we call it like this:
response = await timeout(
getAccessToken(this.state.username, this.state.password),
'Unable to connect to the server.',
);
where getAccessToken
is an async wrapper around fetch
. It works fine on a first login attempt (with Internet down). It waits for five seconds (DEFAULT_TIMEOUT
) and then prints the 'Unable to connect to the server' error message. The problem is that if I click on the login button a second time, the app doesn't wait for five seconds and prints a generic 'Network error'. We can see the problem in logkitty
:
[12:08:44] I | ReactNativeJS ▶︎ timeout called (first click)
[12:08:49] I | ReactNativeJS ▶︎ timeout NOT called (second click)
I don't understand why on a second login attempt the timeout is not triggered and the timeout
automatically fails. What is the problem and how can I fix it?