How to Pass Errors from useFetch to a Nuxt 3 error.page in a Nuxt.js Application?

908 views Asked by At

I'm working on a Nuxt 3 application, and I'm using the useFetch function from nuxt3 to make API requests. I want to handle errors returned by useFetch and pass them to the Nuxt 3 error.page for display.

Here's my current code setup:

In api.ts:

import { useRuntimeConfig, useFetch } from 'nuxt3';

export const api = async (request: string, opts: any) => {
  const config = useRuntimeConfig();

  try {
    const fetch = await useFetch(request, {
      baseURL: config.public.API_BASE_URL,
      ...opts,
      headers: {
        Authorization: `Bearer ${getToken()}`,
      },
    });
      //i tried this one and also CreateError a mentioned into the docs.
    if (fetch.error?.value) {
      throw new Error(
        `${fetch.error.value.statusCode} ${fetch.error.value.statusMessage}`
      );
    }

    return fetch;
  } catch (error) {
    throw error;
  }
};

and In error.vue:

<template>
  <NuxtLayout>
    <CommonLayoutUtilsErrorLayout
      :status-code="error.statusCode"
      :error-message="error.message"
    ></CommonLayoutUtilsErrorLayout>
  </NuxtLayout>
</template>

<script>
export default {
  props: {
    error: {
      type: Object,
      default: null,
    },
    errorMessage: String,
  },
  useHead() {
    return {
      title: `${this.error.statusCode} Error`,
    };
  },
};
</script>

I want to know how to properly pass errors from the useFetch function to the error.page in Nuxt 3 so that I can display the error message and status code on the error page. Any guidance or examples would be greatly appreciated. Thank you!

I tried this one

if (fetch.error?.value) {
      throw new Error(
        `${fetch.error.value.statusCode} ${fetch.error.value.statusMessage}`
      );
 }

and this one too


 if (fetch.error?.value) {
    // throw createError({ statusCode: fetch.error?.value?.statusCode, message: fetch.error?.value?.statusMessage })
    throw createError({ statusCode: 404, statusMessage: 'Page Not Found', fatal: true })
  }
2

There are 2 answers

1
Reagan On

The useFetch composable has an error object available as a return value. See example

A simple example would be something like this.

<script lang="ts" setup>
const { error } = await useFetch('/api/')
if (error.value) {
  // Simple error handling.
  throw createError({ statusCode: 500, statusMessage: 'Something went wrong', fatal: false })
  // OR, if you have a full control of your API and you want to display the error from the API response.
  throw createError({ statusCode: error.value?.statusCode, statusMessage: error.value?.statusMessage, fatal: true })
}
</script>

On the client side, by default, it will throw a non-fatal error for you to handle. If you need to trigger a full-screen error page, then you can do this by setting fatal: true(See my example).

error.vue

<script lang="ts" setup>
import { H3Error } from 'h3'
defineProps<{ error: H3Error }>()
</script>
<template>
  <div>
    {{ error.statusCode }}
    {{ error.statusMessage }}
  </div>
</template>

If you also want to clear the error. Check this doc

Hope that helps.

0
Sushil Tiwari On

I solved this by using like this

if (fetch.error?.value?.statusCode && ![412, 428, 429].includes(fetch.error?.value?.statusCode)) {
    throw showError({
      statusCode: fetch.error?.value?.statusCode,
      message: fetch.error?.value?.statusMessage,
      fatal: true,
    })
  }