Error Handling
The server proxy passes your API's error through untouched – status code, status message, headers and body all reach your app, so a 404, a validation error and a 500 stay distinguishable.
Error Types
Composables – useMyApiData
The useMyApiData composables integrate with Nuxt's error handling and expose errors through the error property, following Nuxt's useAsyncData pattern:
vue
<script setup lang="ts">
const { data, error } = await useJsonPlaceholderData('posts/invalid-id')
if (error.value) {
console.error('Request failed:', error.value.statusText)
console.error('Status code:', error.value.status)
console.error('Response data:', error.value.data)
}
</script>
<template>
<div>
<div v-if="error">
<h3>Error: {{ error.statusText }}</h3>
<p>{{ error.data?.message || 'Something went wrong' }}</p>
</div>
<div v-else-if="data">
<!-- Success content -->
<h1>{{ data.title }}</h1>
</div>
</div>
</template>Functions – $myApi
The $myApi functions throw errors directly since they're designed for programmatic use (like form submissions or one-time actions):
vue
<script setup lang="ts">
import type { FetchError } from 'ofetch'
async function createPost() {
try {
const result = await $jsonPlaceholder('posts', {
method: 'POST',
body: {
title: 'New Post',
body: 'Content here'
}
})
console.log('Post created:', result)
}
catch (error) {
const _error = error as FetchError
console.error('Request failed:', _error.statusMessage)
console.error('Status code:', _error.statusCode)
console.error('Response data:', _error.data)
}
}
</script>Type Declarations
FetchError Interface
The FetchError type from ofetch is used for errors thrown by $myApi functions:
ts
interface FetchError<T = any> extends Error {
request?: FetchRequest
options?: FetchOptions
response?: FetchResponse<T>
data?: T
status?: number
statusText?: string
statusCode?: number
statusMessage?: string
}NuxtError Interface
The NuxtError type is used for errors returned by useMyApiData composables:
ts
interface NuxtError<DataT = unknown> extends Omit<H3Error<DataT>, 'statusCode' | 'statusMessage'>, Error {
readonly __nuxt_error?: true
error?: true
status?: number
statusText?: string
/** @deprecated Use `status` */
statusCode?: H3Error<DataT>['statusCode']
/** @deprecated Use `statusText` */
statusMessage?: H3Error<DataT>['statusMessage']
}
declare class H3Error<DataT = unknown> extends Error {
static __h3_error__: boolean
statusCode: number
fatal: boolean
unhandled: boolean
statusMessage?: string
data?: DataT
cause?: unknown
constructor(message: string, opts?: {
cause?: unknown
})
toJSON(): Pick<H3Error<DataT>, 'message' | 'statusCode' | 'statusMessage' | 'data'>
}