unjs/nitroだと、自作のエラーハンドラーを設定できるので、
ErrorからAPIレスポンスに変換したりもできる
// ~/error.ts import { EventHandlerRequest, H3Error, H3Event } from "h3"; export default defineNitroErrorHandler((error: H3Error, event: H3Event<EventHandlerRequest>) => { // H3Errorを、いい感じに、共通ErrorResponseに変換 const res = { message: `${error}`, /* ... */}; // ステータスコードを設定(例) setResponseStatus(event, error.statusCode); // 共通ErrorResponseをレスポンスに設定して返却 return send(event, JSON.stringify(res)); });
// nitro.config.ts export default defineNitroConfig({ errorHandler: "~/error", });
server/
を使ったSSRなNuxtでも、API部分はこれを使いたいなと思い、
いろいろ調べたときの備忘録(*´ω`*)
そのままだとダメ
Nuxtでもnitroの設定ができるので、そのまま試してみたけどダメだった。。。
すべてのErrorがハンドリングされてしまい、error.vue
が表示されない。。。
// nuxt.config.ts // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ nitro: { errorHandler: "~~/server/error.ts", } });
Nuxt側でもnitro.errorHandler
を利用しているようで、
Nuxt側が設定したNitroErrorHandler
を上書きしてしまい、
すべてがjson形式になってしまうよう。。。
やったこと
まさになIssueがあったので、これを参考にワークアラウンド対応した
すべてのAPIがserver/routes/api/*
になる前提で、
パスが/api/
以外は、NuxtのNitroErrorHandler
を使う形
import { EventHandlerRequest, H3Error, H3Event } from "h3"; import nuxtErrorHandler from '~~/node_modules/nuxt/dist/core/runtime/nitro/error.js'; export default defineNitroErrorHandler((error: H3Error, event: H3Event<EventHandlerRequest>) => { // /api配下以外はNuxtのerrorHandlerを使う if (!event.node.req.originalUrl?.startsWith("/api")) { return nuxtErrorHandler(error, event); } // 以下は同じ // H3Errorを、いい感じに、共通ErrorResponseに変換 const res = { message: `${error}`, /* ... */}; setResponseStatus(event, error.statusCode); return send(event, JSON.stringify(res)); });
残念ながら、exportはされていないので、
node_modules/nuxt/dist
からimportしている
v3.15.2だと、ここにあるerrorhandler
を利用している
以上! これで、Nuxtのserver/
ディレクトリでも、defineNitroErrorHandler
を利用できて、
エラーレスポンスの共通化が簡単になった(*´ω`*)