DEV Community

v0id-4lps
v0id-4lps

Posted on • Edited on

Nuxt3 : API error handling

Hello World

First post here, hello world!

Context

  • Nuxt 3.10.3
  • Vue 3.4.15

In Nuxt 3.10.3 you can't retrieve custom error message properly.

If you write a custom error message you cannot be able to retrieve it without a little but dirty workaround.

Example

Here is a short example :

  1. A simple API event handler throwing a basic error
  2. A simple page with 2 actions:
    • getting an error with $fetch()
    • getting an error with useFetch()
    • and displaying the result
# /pages/error.vue

<template>
    <p><button @click="onClickFetch">GetError with $fetch()</button></p>
    <p><button @click="onClickUseFetch">GetError with useFetch()</button></p>
    <pre v-if="myError">
- statusCode: {{ myError.statusCode }}
- statusMessage: {{ myError.statusMessage }}
- message: {{ myError.message }}
- data: {{ myError.data }}
    </pre>
</template>

<script setup lang="ts">
const myError = useState('myError')

const onClickFetch = async e => {
    myError.value = null;
    try {
        const data = await $fetch('/api/error')
    } catch (error) {
        myError.value = error
    }
}

const onClickUseFetch = async e => {
    myError.value = null;
    const { data, error, execute, pending, refresh, status } = await useFetch('/api/error')
    myError.value = error
}
</script>
Enter fullscreen mode Exit fullscreen mode
# /server/api/error.ts

export default defineEventHandler(async event => {
    throw createError({
        statusCode: 500,
        statusMessage: 'MyError statusMessage (éàè)',
        message: 'MyError message (éàè)'
        data: {
            data: {
                message: `MyError data message (éàè)`,
            },
        },
    })
})
Enter fullscreen mode Exit fullscreen mode

Result

- statusCode: 500
- statusMessage: Internal Server Error
- message: [GET] "/api/error": 500 Internal Server Error
- data:
{
    data: {
        message: `MyError data message (éàè)`,
    },
}
Enter fullscreen mode Exit fullscreen mode

As you can see, .statusMessage and .message are not returning your custom message.

Workaround

Dirty workaround : use .data to pass your custom error message.

# /server/api/error.ts

export default defineEventHandler(async event => {
    throw createError({
        statusCode: 500,
        statusMessage: 'Internal Server Error',
        // Here we have to define the `data` property
        data: {
            message: `My custom error message`,
        },
    })
})
Enter fullscreen mode Exit fullscreen mode
<template>
    <div v-if="myError">
        <!-- Here we have to use .data.data.message -->
        <p>{{ myError.data.data.message }}</p>
    </div>
</template>

<script setup lang="ts">
const myError = useState('myError')

try {
    const data = await $fetch('/api/error')
} catch (error) {
    myError.value = error
}
</script>
Enter fullscreen mode Exit fullscreen mode

It's dirty because your have to do 2 things :

  1. writing the data block on every error you want to throw
  2. using .data.data.message every time you want to display your message

Not found a better solution from now.

If you know a better solution, please, let us know in comment.

Top comments (0)