Added APIError en exception to filter out any system Error providing an easy way to handle business errors with translations
This commit is contained in:
+32
-5
@@ -9,6 +9,7 @@ import User from "./models/User";
|
|||||||
import Constants from "expo-constants";
|
import Constants from "expo-constants";
|
||||||
import store from "./state/Store";
|
import store from "./state/Store";
|
||||||
import { Platform } from "react-native";
|
import { Platform } from "react-native";
|
||||||
|
import { en } from "./i18n/Translations";
|
||||||
|
|
||||||
type AuthenticationInput = { username: string; password: string };
|
type AuthenticationInput = { username: string; password: string };
|
||||||
type RegistrationInput = AuthenticationInput & { email: string };
|
type RegistrationInput = AuthenticationInput & { email: string };
|
||||||
@@ -22,8 +23,23 @@ type FetchParams = {
|
|||||||
raw?: true;
|
raw?: true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const dummyIllustrations =
|
// This Exception is intended to cover all business logic errors (invalid credentials, couldn't find a song, etc.)
|
||||||
[
|
// technical errors (network, server, etc.) should be handled as standard Error exceptions
|
||||||
|
// it helps to filter errors in the catch block, APIErrors messages should
|
||||||
|
// be safe to use in combination with the i18n library
|
||||||
|
export class APIError extends Error {
|
||||||
|
constructor(
|
||||||
|
message: string,
|
||||||
|
public status: number,
|
||||||
|
// Set the message to the correct error this is a placeholder
|
||||||
|
// when the error is only used internally (middleman)
|
||||||
|
public userMessage : keyof typeof en = "unknownError"
|
||||||
|
) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const dummyIllustrations = [
|
||||||
"https://i.discogs.com/syRCX8NaLwK2SMk8X6TVU_DWc8RRqE4b-tebAQ6kVH4/rs:fit/g:sm/q:90/h:600/w:600/czM6Ly9kaXNjb2dz/LWRhdGFiYXNlLWlt/YWdlcy9SLTgyNTQz/OC0xNjE3ODE0NDI2/LTU1MjUuanBlZw.jpeg",
|
"https://i.discogs.com/syRCX8NaLwK2SMk8X6TVU_DWc8RRqE4b-tebAQ6kVH4/rs:fit/g:sm/q:90/h:600/w:600/czM6Ly9kaXNjb2dz/LWRhdGFiYXNlLWlt/YWdlcy9SLTgyNTQz/OC0xNjE3ODE0NDI2/LTU1MjUuanBlZw.jpeg",
|
||||||
"https://folkr.fr/wp-content/uploads/2017/06/dua-lipa-folkr-2017-cover-04.jpg",
|
"https://folkr.fr/wp-content/uploads/2017/06/dua-lipa-folkr-2017-cover-04.jpg",
|
||||||
"https://folkr.fr/wp-content/uploads/2017/06/dua-lipa-folkr-2017-cover-03.jpg",
|
"https://folkr.fr/wp-content/uploads/2017/06/dua-lipa-folkr-2017-cover-03.jpg",
|
||||||
@@ -56,16 +72,20 @@ export default class API {
|
|||||||
header,
|
header,
|
||||||
body: JSON.stringify(params.body),
|
body: JSON.stringify(params.body),
|
||||||
method: params.method ?? "GET",
|
method: params.method ?? "GET",
|
||||||
|
}).catch(() => {
|
||||||
|
throw new Error("Error while fetching API: " + baseAPIUrl);
|
||||||
});
|
});
|
||||||
if (params.raw) {
|
if (params.raw) {
|
||||||
return response.arrayBuffer();
|
return response.arrayBuffer();
|
||||||
}
|
}
|
||||||
const body = await response.text();
|
const body = await response.text();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const jsonResponse = body.length != 0 ? JSON.parse(body) : {};
|
const jsonResponse = body.length != 0 ? JSON.parse(body) : {};
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(jsonResponse.error ?? response.statusText);
|
throw new APIError(
|
||||||
|
jsonResponse ?? response.statusText,
|
||||||
|
response.status
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return jsonResponse;
|
return jsonResponse;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -82,7 +102,14 @@ export default class API {
|
|||||||
route: "/auth/login",
|
route: "/auth/login",
|
||||||
body: authenticationInput,
|
body: authenticationInput,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
}).then((responseBody) => responseBody.access_token);
|
})
|
||||||
|
.then((responseBody) => responseBody.access_token)
|
||||||
|
.catch((e) => {
|
||||||
|
if (!(e instanceof APIError)) throw e;
|
||||||
|
|
||||||
|
if (e.status == 401) throw new APIError("invalidCredentials", 401, "invalidCredentials");
|
||||||
|
throw e;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Create a new user profile, with an email and a password
|
* Create a new user profile, with an email and a password
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ export const en = {
|
|||||||
forgottenPassword: 'Forgotten password',
|
forgottenPassword: 'Forgotten password',
|
||||||
|
|
||||||
partition: 'Partition',
|
partition: 'Partition',
|
||||||
|
unknownError: 'Unknown error',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fr: typeof en = {
|
export const fr: typeof en = {
|
||||||
@@ -182,6 +183,7 @@ export const fr: typeof en = {
|
|||||||
forgottenPassword: "Mot de passe oublié",
|
forgottenPassword: "Mot de passe oublié",
|
||||||
|
|
||||||
partition: 'Partition',
|
partition: 'Partition',
|
||||||
|
unknownError: 'Erreur inconnue',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sp: typeof en = {
|
export const sp: typeof en = {
|
||||||
@@ -277,4 +279,5 @@ export const sp: typeof en = {
|
|||||||
repeatPassword: 'Répéter le mot de passe',
|
repeatPassword: 'Répéter le mot de passe',
|
||||||
|
|
||||||
partition: 'Partition',
|
partition: 'Partition',
|
||||||
|
unknownError: 'Error desconocido',
|
||||||
};
|
};
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { useDispatch } from '../state/Store';
|
import { useDispatch } from '../state/Store';
|
||||||
import { Translate, translate } from "../i18n/i18n";
|
import { Translate, translate } from "../i18n/i18n";
|
||||||
import API from "../API";
|
import API, { APIError } from "../API";
|
||||||
import { setAccessToken } from "../state/UserSlice";
|
import { setAccessToken } from "../state/UserSlice";
|
||||||
import { Center, Button, Text } from 'native-base';
|
import { Center, Button, Text } from 'native-base';
|
||||||
import SigninForm from "../components/forms/signinform";
|
import SigninForm from "../components/forms/signinform";
|
||||||
@@ -14,7 +14,9 @@ const hanldeSignin = async (username: string, password: string, apiSetter: (acce
|
|||||||
apiSetter(apiAccess);
|
apiSetter(apiAccess);
|
||||||
return translate("loggedIn");
|
return translate("loggedIn");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return "Username or password incorrect";
|
if (error instanceof APIError) return translate(error.userMessage);
|
||||||
|
if (error instanceof Error) return error.message;
|
||||||
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user