Handle api error json (#18)

* Handle api error json

* Fix get vehicles error handling
Update .env.template
This commit is contained in:
John Wu
2021-03-17 15:11:41 -07:00
committed by GitHub
parent 2e1f4a7a7c
commit bf401e68eb
10 changed files with 69 additions and 47 deletions

View File

@@ -1,2 +1,3 @@
REACT_APP_AUTH_SERVICE_URL = https://dev-auth.fiskerdps.com REACT_APP_AUTH_SERVICE_URL = https://dev-auth.fiskerdps.com
REACT_APP_UPLOAD_SERVICE_URL = https://gw-dev.fiskerdps.com REACT_APP_UPLOAD_SERVICE_URL = https://gw-dev.fiskerdps.com
REACT_APP_AUTH_CALLBACK_URL = https://dev-ota-admin.fiskerdps.com/

View File

@@ -20,10 +20,7 @@ export const UserProvider = ({ children }) => {
useEffect(() => { useEffect(() => {
if (!token) return; if (!token) return;
const { verifyToken();
idToken: { jwtToken },
} = token;
verifyToken(jwtToken);
return () => { return () => {
if (timer) timer.terminate(); if (timer) timer.terminate();
}; };
@@ -57,15 +54,14 @@ export const UserProvider = ({ children }) => {
timer.start(duration); timer.start(duration);
}; };
const verifyToken = async (idToken) => { const verifyToken = async () => {
try { try {
const {
idToken: { jwtToken: idToken },
} = token;
const result = await auth.verify(idToken); const result = await auth.verify(idToken);
if ( if (!result && !result.valid) {
(!result.valid && !result.authenticated) ||
!token.idToken.payload ||
!token.idToken.payload.exp
) {
const t = await refreshTokens(); const t = await refreshTokens();
if (!isError(t)) return; if (!isError(t)) return;
signOut(); signOut();
@@ -74,7 +70,8 @@ export const UserProvider = ({ children }) => {
startSessionTimer(); startSessionTimer();
} catch (e) { } catch (e) {
setError(e.message); signOut();
setError(`Verify error. ${e.message}`);
} }
}; };
@@ -126,7 +123,6 @@ export const UserProvider = ({ children }) => {
setFetching(true); setFetching(true);
setError(null); setError(null);
// eslint-disable-next-line
result = await auth.refresh(value); result = await auth.refresh(value);
if (result.message) { if (result.message) {

View File

@@ -24,10 +24,13 @@ export const VehicleProvider = ({ children }) => {
const getVehicles = async (search, token) => { const getVehicles = async (search, token) => {
try { try {
setBusy(true); setBusy(true);
const { const result = await api.getVehicles(search, token);
data: { data }, if (result.error) {
} = await api.getVehicles(search, token); setVehicles([]);
setVehicles(data); throw new Error(`Get vehicles error. ${result.message}`);
} else {
setVehicles(result.data);
}
} finally { } finally {
setBusy(false); setBusy(false);
} }
@@ -37,7 +40,9 @@ export const VehicleProvider = ({ children }) => {
try { try {
setBusy(true); setBusy(true);
validateAdd(vehicle); validateAdd(vehicle);
await api.addVehicle(vehicle, token); const result = await api.addVehicle(vehicle, token);
if (result.error) throw new Error(`Add vehicle error. ${result.message}`);
return result;
} finally { } finally {
setBusy(false); setBusy(false);
} }

View File

@@ -131,12 +131,14 @@ describe("VehicleContext", () => {
}); });
}); });
const expectedVehicleData = [ const expectedVehicleData = {
{ vin: "3C4PDCBG0ET127145" }, data: [
{ vin: "1G1FP87S3GN100062" }, { vin: "3C4PDCBG0ET127145" },
{ vin: "1HGCG325XYA062256" }, { vin: "1G1FP87S3GN100062" },
{ vin: "1J4GZ78YXWC160024" }, { vin: "1HGCG325XYA062256" },
{ vin: "2C3CCAAG8CH222800" }, { vin: "1J4GZ78YXWC160024" },
{ vin: "KNADM4A39C6028108" }, { vin: "2C3CCAAG8CH222800" },
{ vin: "1G11C5SL9FF153507" }, { vin: "KNADM4A39C6028108" },
]; { vin: "1G11C5SL9FF153507" },
],
};

View File

@@ -43,7 +43,6 @@ const FileUploadZone = ({ classes, token }) => {
onChange={(files) => setFiles(files)} onChange={(files) => setFiles(files)}
onDelete={(files) => setFiles(files)} onDelete={(files) => setFiles(files)}
onDropRejected={(files) => { onDropRejected={(files) => {
console.log("Rejected files", files);
setMessage(`Rejected ${files[0].name} too large`); setMessage(`Rejected ${files[0].name} too large`);
}} }}
/> />

View File

@@ -24,9 +24,9 @@ const MainForm = () => {
vin: vinEl.current.value, vin: vinEl.current.value,
}; };
await addVehicle(formData, authToken); const result = await addVehicle(formData, authToken);
setMessage(`Added ${vinEl.current.value}`); setMessage(`Added ${result.vin}`);
vinEl.current.value = ""; vinEl.current.value = "";
} catch (e) { } catch (e) {
setMessage(e.message); setMessage(e.message);

View File

@@ -11,7 +11,10 @@ const data = [
const vehiclesAPI = { const vehiclesAPI = {
getVehicles: async (search, token) => { return { data: { data } }; }, getVehicles: async (search, token) => { return { data: { data } }; },
addVehicle: async (vehicle, token) => { data.push(vehicle); }, addVehicle: async (vehicle, token) => {
data.push(vehicle);
return vehicle;
},
}; };
export default vehiclesAPI; export default vehiclesAPI;

View File

@@ -1,3 +1,5 @@
import { fetchRespHandler } from "../utils/http";
const AUTH_URL = process.env.REACT_APP_AUTH_SERVICE_URL || "https://gw-dev.fiskerdps.com/compute_auth"; const AUTH_URL = process.env.REACT_APP_AUTH_SERVICE_URL || "https://gw-dev.fiskerdps.com/compute_auth";
const CALLBACK_URL = process.env.REACT_APP_AUTH_CALLBACK_URL || "https://dev-ota-admin.fiskerdps.com"; const CALLBACK_URL = process.env.REACT_APP_AUTH_CALLBACK_URL || "https://dev-ota-admin.fiskerdps.com";
@@ -13,7 +15,7 @@ const auth = {
code, code,
redirect: CALLBACK_URL, redirect: CALLBACK_URL,
}) })
}).then((response) => response.json()), }).then(fetchRespHandler),
verify: (idToken) => fetch(`${AUTH_URL}/verify`, { verify: (idToken) => fetch(`${AUTH_URL}/verify`, {
method: "POST", method: "POST",
@@ -21,7 +23,7 @@ const auth = {
"Content-Type": "application/json" "Content-Type": "application/json"
}, },
body: JSON.stringify({ token: idToken }) body: JSON.stringify({ token: idToken })
}).then((response) => response.json()), }).then(fetchRespHandler),
refresh: (refreshToken) => fetch(`${AUTH_URL}/refresh`, { refresh: (refreshToken) => fetch(`${AUTH_URL}/refresh`, {
method: "POST", method: "POST",
@@ -29,7 +31,7 @@ const auth = {
"Content-Type": "application/json" "Content-Type": "application/json"
}, },
body: JSON.stringify({ refresh_token: refreshToken }) body: JSON.stringify({ refresh_token: refreshToken })
}).then((response) => response.json()), }).then(fetchRespHandler),
}; };
export default auth; export default auth;

View File

@@ -1,20 +1,20 @@
import axios from 'axios'; import { getAuthHeaderOptions, fetchRespHandler } from "../utils/http"
const API_ENDPOINT = process.env.REACT_APP_UPLOAD_SERVICE_URL || "https://gw-dev.fiskerdps.com/ota_update"; const API_ENDPOINT = process.env.REACT_APP_UPLOAD_SERVICE_URL || "https://gw-dev.fiskerdps.com/ota_update";
const getOptions = (token) => ({
headers: {
"Authorization": `Bearer ${token}`,
},
});
const vehiclesAPI = { const vehiclesAPI = {
getVehicles: async (search, token) => { addVehicle: async (vehicle, token) => fetch(`${API_ENDPOINT}/vehicle`, {
return axios.get(`${API_ENDPOINT}/vehicles`, getOptions(token)); method: "POST",
}, headers: Object.assign({ "Content-Type": "application/json" }, getAuthHeaderOptions(token)),
addVehicle: async (vehicle, token) => { body: JSON.stringify(vehicle),
return axios.post(`${API_ENDPOINT}/vehicle`, vehicle, getOptions(token)); })
} .then(fetchRespHandler),
getVehicles: async (search, token) => fetch(`${API_ENDPOINT}/vehicles`, {
method: "GET",
headers: Object.assign({ "Content-Type": "application/json" }, getAuthHeaderOptions(token)),
})
.then(fetchRespHandler)
}; };
export default vehiclesAPI; export default vehiclesAPI;

14
src/utils/http.js Normal file
View File

@@ -0,0 +1,14 @@
export const getAuthHeaderOptions = (token) => ({
"Authorization": `Bearer ${token}`,
});
export const fetchRespHandler = (response) => {
if (response.ok) return response.json();
return response.text()
.then((text) => JSON.parse(text))
.catch((e) => ({
error: response.statusText,
message: `${response.status} ${response.statusText}`,
}))
}