From e687b58091bcedb6f3a56d94030fa312e51830d5 Mon Sep 17 00:00:00 2001
From: taehoon
Date: Thu, 21 Feb 2019 13:32:47 -0500
Subject: [PATCH 1/2] Show error message when visit profile page of invalid
user
---
src/components/user_profile/user_profile.js | 8 ++++++++
src/components/user_profile/user_profile.vue | 3 ++-
src/i18n/en.json | 3 ++-
src/modules/users.js | 2 +-
src/services/api/api.service.js | 6 ++++++
5 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index 37179ce156..44192e9a32 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -4,6 +4,11 @@ import Timeline from '../timeline/timeline.vue'
import FollowList from '../follow_list/follow_list.vue'
const UserProfile = {
+ data () {
+ return {
+ error: false
+ }
+ },
created () {
this.$store.commit('clearTimeline', { timeline: 'user' })
this.$store.commit('clearTimeline', { timeline: 'favorites' })
@@ -13,6 +18,9 @@ const UserProfile = {
this.startFetchFavorites()
if (!this.user.id) {
this.$store.dispatch('fetchUser', this.fetchBy)
+ .catch(() => {
+ this.error = true
+ })
}
},
destroyed () {
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 09fb93deb0..ccebe20b99 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -55,7 +55,8 @@
-
+ {{ $t('user_profile.profile_does_not_exist') }}
+
diff --git a/src/i18n/en.json b/src/i18n/en.json
index 64753f1dc1..c482ecb6f7 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -383,7 +383,8 @@
"mute_progress": "Muting..."
},
"user_profile": {
- "timeline_title": "User Timeline"
+ "timeline_title": "User Timeline",
+ "profile_does_not_exist": "Sorry, this profile does not exist."
},
"who_to_follow": {
"more": "More",
diff --git a/src/modules/users.js b/src/modules/users.js
index 77df7168e2..eabfe5ae22 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -140,7 +140,7 @@ const users = {
getters,
actions: {
fetchUser (store, id) {
- store.rootState.api.backendInteractor.fetchUser({ id })
+ return store.rootState.api.backendInteractor.fetchUser({ id })
.then((user) => store.commit('addNewUsers', [user]))
},
fetchBlocks (store) {
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 3d2e8823a5..d87165962a 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -244,6 +244,12 @@ const denyUser = ({id, credentials}) => {
const fetchUser = ({id, credentials}) => {
let url = `${USER_URL}?user_id=${id}`
return fetch(url, { headers: authHeaders(credentials) })
+ .then((data) => {
+ if (!data.ok) {
+ throw Error(data.statusText)
+ }
+ return data
+ })
.then((data) => data.json())
.then((data) => parseUser(data))
}
From b78227456ea6b1a80cd85988d3ef91cb654a881c Mon Sep 17 00:00:00 2001
From: taehoon
Date: Tue, 26 Feb 2019 12:26:04 -0500
Subject: [PATCH 2/2] Better error handling
---
src/components/user_profile/user_profile.js | 12 ++++++++++--
src/components/user_profile/user_profile.vue | 2 +-
src/i18n/en.json | 3 ++-
src/services/api/api.service.js | 15 +++++++++------
src/services/errors/errors.js | 14 ++++++++++++++
5 files changed, 36 insertions(+), 10 deletions(-)
create mode 100644 src/services/errors/errors.js
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index 44192e9a32..ebf6c61ae1 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -1,3 +1,4 @@
+import get from 'lodash/get'
import UserCardContent from '../user_card_content/user_card_content.vue'
import UserCard from '../user_card/user_card.vue'
import Timeline from '../timeline/timeline.vue'
@@ -18,8 +19,15 @@ const UserProfile = {
this.startFetchFavorites()
if (!this.user.id) {
this.$store.dispatch('fetchUser', this.fetchBy)
- .catch(() => {
- this.error = true
+ .catch((reason) => {
+ const errorMessage = get(reason, 'error.error')
+ if (errorMessage === 'No user with such user_id') { // Known error
+ this.error = this.$t('user_profile.profile_does_not_exist')
+ } else if (errorMessage) {
+ this.error = errorMessage
+ } else {
+ this.error = this.$t('user_profile.profile_loading_error')
+ }
})
}
},
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index ccebe20b99..ba1a7760d2 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -55,7 +55,7 @@
- {{ $t('user_profile.profile_does_not_exist') }}
+ {{ error }}
diff --git a/src/i18n/en.json b/src/i18n/en.json
index c482ecb6f7..9fdd1692e7 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -384,7 +384,8 @@
},
"user_profile": {
"timeline_title": "User Timeline",
- "profile_does_not_exist": "Sorry, this profile does not exist."
+ "profile_does_not_exist": "Sorry, this profile does not exist.",
+ "profile_loading_error": "Sorry, there was an error loading this profile."
},
"who_to_follow": {
"more": "More",
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index d87165962a..fbe5afa0a7 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -47,6 +47,7 @@ const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites'
import { each, map } from 'lodash'
import { parseStatus, parseUser, parseNotification } from '../entity_normalizer/entity_normalizer.service.js'
import 'whatwg-fetch'
+import { StatusCodeError } from '../errors/errors'
const oldfetch = window.fetch
@@ -244,13 +245,15 @@ const denyUser = ({id, credentials}) => {
const fetchUser = ({id, credentials}) => {
let url = `${USER_URL}?user_id=${id}`
return fetch(url, { headers: authHeaders(credentials) })
- .then((data) => {
- if (!data.ok) {
- throw Error(data.statusText)
- }
- return data
+ .then((response) => {
+ return new Promise((resolve, reject) => response.json()
+ .then((json) => {
+ if (!response.ok) {
+ return reject(new StatusCodeError(response.status, json, { url }, response))
+ }
+ return resolve(json)
+ }))
})
- .then((data) => data.json())
.then((data) => parseUser(data))
}
diff --git a/src/services/errors/errors.js b/src/services/errors/errors.js
new file mode 100644
index 0000000000..548f3c689b
--- /dev/null
+++ b/src/services/errors/errors.js
@@ -0,0 +1,14 @@
+export function StatusCodeError (statusCode, body, options, response) {
+ this.name = 'StatusCodeError'
+ this.statusCode = statusCode
+ this.message = statusCode + ' - ' + (JSON && JSON.stringify ? JSON.stringify(body) : body)
+ this.error = body // legacy attribute
+ this.options = options
+ this.response = response
+
+ if (Error.captureStackTrace) { // required for non-V8 environments
+ Error.captureStackTrace(this)
+ }
+}
+StatusCodeError.prototype = Object.create(Error.prototype)
+StatusCodeError.prototype.constructor = StatusCodeError