From 43e860d3c54a6f89f043e23b8397acd99caf88fe Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Fri, 5 Jul 2019 13:41:43 +0200 Subject: [PATCH] auth/data: avoid setting global errors when receiving a 401 If we do a router.push to the login view the previous component will receive anyway the error and set the global error after the login view is mounted (!!!) and so the main app will show the global error instead of the login view. Not sure how to avoid this. As a really ugly workaround just return an empty response on 401 so the components (since they are currently assumong the response is always define) will throw an exception and not set the global error. --- src/util/auth.js | 12 +++--------- src/util/data.js | 18 ++++++++++++++++++ src/views/Login.vue | 3 +++ src/views/Register.vue | 3 +++ 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/util/auth.js b/src/util/auth.js index f017ee3..6ebcaf0 100644 --- a/src/util/auth.js +++ b/src/util/auth.js @@ -1,4 +1,3 @@ -import router from "@/router"; import store from "@/store"; const ID_TOKEN_KEY = 'id_token'; @@ -54,8 +53,7 @@ export async function loginapi(init) { } try { - let res = await window.fetch(loginurl(), init) - return res + return await window.fetch(loginurl(), init) } catch (e) { throw e } @@ -67,8 +65,7 @@ export async function registerapi(init) { } try { - let res = await window.fetch(registerurl(), init) - return res + return await window.fetch(registerurl(), init) } catch (e) { throw e } @@ -87,10 +84,7 @@ export async function fetch(url, init) { } try { - let res = await window.fetch(url, init) - if (res.status === 401) { - router.push({ name: "login" }) - } else { return res } + return await window.fetch(url, init) } catch (e) { throw e } diff --git a/src/util/data.js b/src/util/data.js index 1de5b64..d51d86a 100644 --- a/src/util/data.js +++ b/src/util/data.js @@ -1,10 +1,27 @@ import { apiurl, loginapi, registerapi } from "@/util/auth"; import { fetch as authfetch } from "@/util/auth"; +import router from "@/router"; export async function fetch(url, init) { try { let res = await authfetch(url, init) if (!res.ok) { + if (res.status === 401) { + router.push({ name: "login" }) + // if we return a response containing an error what happens is + // that router.push mounts the login view before the calling + // component processed the response and the calling component + // may set the "unauthorized" error as a global error hiding the + // login view. + // So return an empty response so the caller won't set a global + // error (but in the console will appear other errors since also + // data is null) + + // TODO(sgotti) find a way to make this cleaner. The solution + // could be to find a way to firstly let the component handle + // the error and the do the router push... + return + } let data = await res.json() return { data: null, error: data.message } } else { @@ -86,6 +103,7 @@ export async function fetchRuns(group, startRunID, lastrun) { if (startRunID) { u.searchParams.append("start", startRunID) } + return await fetch(u) } diff --git a/src/views/Login.vue b/src/views/Login.vue index 7c648e8..037c346 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -77,6 +77,9 @@ export default { this.$router.push({ name: "home" }); } }, + mounted: function() { + this.$store.dispatch("setError", null); + }, created: function() { doLogout(); this.fetchRemoteSources(); diff --git a/src/views/Register.vue b/src/views/Register.vue index 095dafb..8b88ecd 100644 --- a/src/views/Register.vue +++ b/src/views/Register.vue @@ -125,6 +125,9 @@ export default { this.$router.push({ name: "home" }); } }, + mounted: function() { + this.$store.dispatch("setError", null); + }, created: function() { doLogout(); this.fetchRemoteSources();