Skip to content

Commit

Permalink
Serialize errors we encounter
Browse files Browse the repository at this point in the history
This PR makes it so that we serialize errors if we're going to send them across the SSR boundary. The problem this fixes is that some errors (like Nuxt reporting composable usage outside a `setup` function) have functions and other non-POJO/non-serializable info with them, which makes our `useState<Error>` implode, ironically hiding the original error.

This introduces a new non-dev dependency (which I don't do lightly) on `serialize-error`, a small (<1kB min + gzip'd) and popular dependency for doing the surprisingly nontrivial task of serializing different types of errors and preserving type information.
  • Loading branch information
bcspragu committed Nov 17, 2023
1 parent a834592 commit 0d276f8
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 6 deletions.
4 changes: 3 additions & 1 deletion frontend/app.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<script setup lang="ts">
import { serializeError } from 'serialize-error'
const { loading: { clearLoading }, error: { errorModalVisible, error } } = useModal()
const handleError = (err: Error) => {
error.value = err
error.value = serializeError(err)
errorModalVisible.value = true
clearLoading()
}
Expand Down
4 changes: 3 additions & 1 deletion frontend/components/modal/Error.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script setup lang="ts">
import { deserializeError } from 'serialize-error'
const { error: { errorModalVisible, error: modalError } } = useModal()
const error = useError()
const router = useRouter()
Expand Down Expand Up @@ -26,7 +28,7 @@ const maybeGoBack = async () => {
}
const fullError = computed(() => {
const err = error.value ?? modalError.value
const err = error.value ?? deserializeError(modalError.value)
if (err instanceof Error) {
return {
name: err.name ?? '',
Expand Down
3 changes: 2 additions & 1 deletion frontend/composables/useModal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type Ref } from 'vue'
import { type ErrorObject } from 'serialize-error'

export const useModal = () => {
const prefix = 'useModal'
Expand All @@ -22,7 +23,7 @@ export const useModal = () => {

// error
const errorModalVisible = newModalVisibilityState('errorModalVisible')
const error = useState<Error>('errorModal.error')
const error = useState<ErrorObject>('errorModal.error')

// loading
const loadingSet = useState<Set<string>>(`${prefix}.loadingSet`, () => new Set<string>())
Expand Down
27 changes: 24 additions & 3 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"primeflex": "^3.3.1",
"primeicons": "^6.0.1",
"primevue": "^3.32.0",
"serialize-error": "^11.0.3",
"uuid": "^9.0.0",
"vue-i18n": "^9.5.0"
}
Expand Down

0 comments on commit 0d276f8

Please sign in to comment.