Skip to content

Commit

Permalink
Handle errors consistently in Tool Shed client
Browse files Browse the repository at this point in the history
  • Loading branch information
davelopez committed Aug 13, 2024
1 parent 1e5639a commit 30e39ea
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 145 deletions.
8 changes: 5 additions & 3 deletions lib/tool_shed/webapp/frontend/src/components/RegisterPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { ref } from "vue"
import ModalForm from "@/components/ModalForm.vue"
import { ToolShedApi } from "@/schema"
import { notify } from "@/util"
import { notifyOnCatch } from "@/util"
import router from "@/router"
import { AUTH_FORM_INPUT_PROPS } from "@/constants"
Expand All @@ -26,9 +26,11 @@ async function onRegister() {
bear_field: "",
},
})
if (!data) {
throw new Error("No data returned")
return
}
const query = {
activation_error: data.activation_error ? "true" : "false",
activation_sent: data.activation_sent ? "true" : "false",
Expand All @@ -37,7 +39,7 @@ async function onRegister() {
}
router.push({ path: "/registration_success", query: query })
} catch (e) {
notify(String(e))
notifyOnCatch(e)
}
}
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
import { ref } from "vue"
import { ToolShedApi, components } from "@/schema"
import PageContainer from "@/components/PageContainer.vue"
import { notifyOnCatch } from "@/util"
type IndexResults = components["schemas"]["BuildSearchIndexResponse"]
const searchResults = ref<IndexResults>()
async function onIndex() {
const { data } = await ToolShedApi().PUT("/api/tools/build_search_index")
searchResults.value = data
try {
const { data } = await ToolShedApi().PUT("/api/tools/build_search_index")
searchResults.value = data
} catch (e) {
notifyOnCatch(e)
}
}
</script>
<template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ async function onChange() {
.then(() => {
router.push("/")
})
.catch((e: Error) => {
.catch((e) => {
error.value = errorMessageAsString(e)
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ToolShedApi } from "@/schema"
import type { Repository } from "@/schema/types"
import LoadingDiv from "@/components/LoadingDiv.vue"
import ErrorBanner from "@/components/ErrorBanner.vue"
import { errorMessageAsString } from "@/util"
interface CitableRepositoryPageProps {
username: string
Expand All @@ -16,25 +17,28 @@ const error = ref<string | null>(null)
async function update() {
error.value = null
const { data, error: requestError } = await ToolShedApi().GET("/api/repositories", {
params: {
query: {
owner: props.username,
name: props.repositoryName,
try {
const { data } = await ToolShedApi().GET("/api/repositories", {
params: {
query: {
owner: props.username,
name: props.repositoryName,
},
},
},
})
if (requestError) {
error.value = requestError.err_msg
} else if (data instanceof Array) {
if (data.length == 0) {
error.value = `Repository ${props.username}/${props.repositoryName} is not found`
} else {
const repository: Repository = data[0]
if (repository.id != repositoryId.value) {
repositoryId.value = repository.id
})
if (data instanceof Array) {
if (data.length == 0) {
error.value = `Repository ${props.username}/${props.repositoryName} is not found`
} else {
const repository: Repository = data[0]
if (repository.id != repositoryId.value) {
repositoryId.value = repository.id
}
}
}
} catch (e) {
error.value = errorMessageAsString(e)
}
}
Expand Down
66 changes: 32 additions & 34 deletions lib/tool_shed/webapp/frontend/src/components/pages/ManageApiKey.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { ref, computed } from "vue"
import PageContainer from "@/components/PageContainer.vue"
import { ToolShedApi } from "@/schema"
import { notify, copyAndNotify, notifyOnCatch } from "@/util"
import { notify, copyAndNotify, notifyOnCatch, errorMessageAsString } from "@/util"
import ConfigFileContents from "@/components/ConfigFileContents.vue"
const apiKey = ref<string | null>(null)
Expand All @@ -22,50 +22,48 @@ async function copyKey() {
const params = { encoded_user_id: "current" }
async function init() {
const { data, error } = await ToolShedApi().GET("/api/users/{encoded_user_id}/api_key", {
params: {
path: params,
},
})
if (error) {
notifyOnCatch(new Error(`Error fetching API key: ${error.err_msg}`))
return
try {
const { data } = await ToolShedApi().GET("/api/users/{encoded_user_id}/api_key", {
params: {
path: params,
},
})
apiKey.value = data ?? null
} catch (e) {
notifyOnCatch(new Error(`Error fetching API key: ${errorMessageAsString(e)}`))
}
apiKey.value = data
}
async function deleteKey() {
const { error } = await ToolShedApi().DELETE("/api/users/{encoded_user_id}/api_key", {
params: {
path: params,
},
})
try {
await ToolShedApi().DELETE("/api/users/{encoded_user_id}/api_key", {
params: {
path: params,
},
})
if (error) {
notifyOnCatch(new Error(`Error deactivating API key: ${error.err_msg}`))
return
apiKey.value = null
notify("API key deactivated")
} catch (e) {
notifyOnCatch(new Error(`Error deactivating API key: ${errorMessageAsString(e)}`))
}
apiKey.value = null
notify("API key deactivated")
}
async function recreateKey() {
const { data, error } = await ToolShedApi().POST("/api/users/{encoded_user_id}/api_key", {
params: {
path: params,
},
})
try {
const { data } = await ToolShedApi().POST("/api/users/{encoded_user_id}/api_key", {
params: {
path: params,
},
})
if (error) {
notifyOnCatch(new Error(`Error re-generating API key: ${error.err_msg}`))
return
if (data) {
apiKey.value = data
notify("Re-generated API key")
}
} catch (e) {
notifyOnCatch(new Error(`Error re-generating API key: ${errorMessageAsString(e)}`))
}
apiKey.value = data
notify("Re-generated API key")
}
void init()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import PageContainer from "@/components/PageContainer.vue"
import RepositoryGrid from "@/components/RepositoriesGrid.vue"
import { type RepositoryGridItem, type OnScroll } from "@/components/RepositoriesGridInterface"
import { ToolShedApi, components } from "@/schema"
import { notifyOnCatch } from "@/util"
const query = ref("")
const page = ref(1)
Expand All @@ -14,30 +15,34 @@ type RepositorySearchHit = components["schemas"]["RepositorySearchHit"]
async function doQuery() {
const queryValue = query.value
const { data } = await ToolShedApi().GET("/api/repositories", {
params: {
query: { q: queryValue, page: page.value, page_size: 10 },
},
})
if (query.value != queryValue) {
console.log("query changed.... not using these results...")
return
}
if (!data) {
throw Error("Server response error.")
}
if ("hits" in data) {
if (page.value == 1) {
hits.value = data.hits
} else {
data.hits.forEach((h) => hits.value.push(h))
try {
const { data } = await ToolShedApi().GET("/api/repositories", {
params: {
query: { q: queryValue, page: page.value, page_size: 10 },
},
})
if (query.value != queryValue) {
console.log("query changed.... not using these results...")
return
}
if (hits.value.length >= parseInt(data.total_results)) {
fetchedLastPage.value = true
if (data && "hits" in data) {
if (page.value == 1) {
hits.value = data.hits
} else {
data.hits.forEach((h) => hits.value.push(h))
}
if (hits.value.length >= parseInt(data.total_results)) {
fetchedLastPage.value = true
}
page.value = page.value + 1
} else {
throw Error("Server response structure error.")
}
page.value = page.value + 1
} else {
throw Error("Server response structure error.")
} catch (e) {
notifyOnCatch(e)
}
}
Expand Down
14 changes: 9 additions & 5 deletions lib/tool_shed/webapp/frontend/src/stores/auth.store.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { defineStore } from "pinia"
import { ensureCookie, notifyOnCatch } from "@/util"
import { ensureCookie, errorMessageAsString, notifyOnCatch } from "@/util"

import { ToolShedApi } from "@/schema"

Expand All @@ -12,10 +12,14 @@ export const useAuthStore = defineStore({
}),
actions: {
async setup() {
const { data: user } = await ToolShedApi().GET("/api/users/current")
this.user = user
// store user details and jwt in local storage to keep user logged in between page refreshes
localStorage.setItem("user", user ? JSON.stringify(user) : "null")
try {
const { data: user } = await ToolShedApi().GET("/api/users/current")
this.user = user
// store user details and jwt in local storage to keep user logged in between page refreshes
localStorage.setItem("user", user ? JSON.stringify(user) : "null")
} catch (e) {
console.debug(`Failed to get current user: ${errorMessageAsString(e)}`)
}
},
async login(username: string, password: string) {
const token = ensureCookie("session_csrf_token")
Expand Down
12 changes: 9 additions & 3 deletions lib/tool_shed/webapp/frontend/src/stores/categories.store.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defineStore } from "pinia"

import { ToolShedApi, components } from "@/schema"
import { notifyOnCatch } from "@/util"
type Category = components["schemas"]["Category"]

export const useCategoriesStore = defineStore({
Expand All @@ -12,9 +13,14 @@ export const useCategoriesStore = defineStore({
actions: {
async getAll() {
this.loading = true
const { data: categories } = await ToolShedApi().GET("/api/categories")
this.categories = categories ?? []
this.loading = false
try {
const { data: categories } = await ToolShedApi().GET("/api/categories")
this.categories = categories ?? []
} catch (e) {
notifyOnCatch(e)
} finally {
this.loading = false
}
},
},
getters: {
Expand Down
Loading

0 comments on commit 30e39ea

Please sign in to comment.