From e687b58091bcedb6f3a56d94030fa312e51830d5 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Thu, 21 Feb 2019 13:32:47 -0500
Subject: Show error message when visit profile page of invalid user

---
 src/components/user_profile/user_profile.vue | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'src/components/user_profile/user_profile.vue')

diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 09fb93de..ccebe20b 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -55,7 +55,8 @@
       </div>
     </div>
     <div class="panel-body">
-      <i class="icon-spin3 animate-spin"></i>
+      <span v-if="error">{{ $t('user_profile.profile_does_not_exist') }}</span>
+      <i class="icon-spin3 animate-spin" v-else></i>
     </div>
   </div>
 </div>
-- 
cgit v1.2.3-70-g09d2


From b78227456ea6b1a80cd85988d3ef91cb654a881c Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Tue, 26 Feb 2019 12:26:04 -0500
Subject: 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

(limited to 'src/components/user_profile/user_profile.vue')

diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index 44192e9a..ebf6c61a 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 ccebe20b..ba1a7760 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -55,7 +55,7 @@
       </div>
     </div>
     <div class="panel-body">
-      <span v-if="error">{{ $t('user_profile.profile_does_not_exist') }}</span>
+      <span v-if="error">{{ error }}</span>
       <i class="icon-spin3 animate-spin" v-else></i>
     </div>
   </div>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index c482ecb6..9fdd1692 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 d8716596..fbe5afa0 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 00000000..548f3c68
--- /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
-- 
cgit v1.2.3-70-g09d2

