ご無沙汰しております。
ただいまNext.jsを公式チュートリアルで学習しているのですが、Chapter7の「Fetching Data」で大きく詰まってしまったため、その時の対処を記事として起こしました。
発生したエラー①
チュートリアルでは「Neon」でのセットアップを取り扱っていたのですが、Neonは別の用途で用いる予定がありましたので、「Supabase」の方を使用することにしました。
Supabase自体のセットアップは滞りなくでき、その後もチュートリアルに沿って.envファイルの設定とコーディングは進められ、テストデータの挿入も問題なくできたのですが、localhostで動作確認を行ったところ、下図のエラーが発生しました。
page.tsxの中身を確認しましたが、タイポなどが見当たらなかったのでログを確認すると、404のエラーが出ておりました。
Database Error: NeonDbError: Server error (HTTP status 404): Not Found
at execute (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:1554:29)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async fetchRevenue (webpack-internal:///(rsc)/./app/lib/data.ts:22:22)
at async Page (webpack-internal:///(rsc)/./app/dashboard/page.tsx:17:21) {
code: null,
sourceError: undefined
}
⨯ app\lib\data.ts (27:11) @ fetchRevenue
⨯ Error: Failed to fetch revenue data.
at fetchRevenue (./app/lib/data.ts:27:15)
at async Page (./app/dashboard/page.tsx:17:21)
digest: "507392606"
25 | } catch (error) {
26 | console.error('Database Error:', error);
> 27 | throw new Error('Failed to fetch revenue data.');
| ^
28 | }
29 | }
30 |
GET /dashboard 500 in 5939ms
import { createClient } from '@/utils/supabase/server';
export default async function Instruments() {
const supabase = await createClient();
const { data: instruments } = await supabase.from("instruments").select();
return <pre>{JSON.stringify(instruments, null, 2)}</pre>
}
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
export async function createClient() {
const cookieStore = await cookies()
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch {
// The `setAll` method was called from a Server Component.
// This can be ignored if you have middleware refreshing
// user sessions.
}
},
},
}
)
}
原因と対処①
上記のログを元に調べたところ、どうやらNext.jsにおけるDB接続はデフォルトだとNeonでの接続を想定したつくりになっているらしく、Supabaseでの接続は確立されていないみたいでした。
チュートリアルでNeonを例に挙げていたのは、最も設定の手間がかからないからだと思います。
data.tsのDBとの接続部分を以下に書き換えたところ、挿入したテストデータが画面に表示されました。
- import { sql } from '@vercel/postgres';
+ import { db } from '@vercel/postgres';
import {
CustomerField,
CustomersTableType,
InvoiceForm,
InvoicesTable,
LatestInvoiceRaw,
Revenue,
} from './definitions';
import { formatCurrency } from './utils';
export async function fetchRevenue() {
try {
// Artificially delay a response for demo purposes.
// Don't do this in production :)
console.log('Fetching revenue data...');
await new Promise((resolve) => setTimeout(resolve, 3000));
- const data = await sql<Revenue>`SELECT * FROM revenue`;
+ const client = await db.connect();
+ const data = await client.sql<Revenue>`SELECT * FROM revenue`;
console.log('Data fetch completed after 3 seconds.');
return data.rows;
} catch (error) {
console.error('Database Error:', error);
throw new Error('Failed to fetch revenue data.');
}
}
発生したエラー②
localhostで画面表示ができたのでリポジトリにプッシュしVercelへデプロイしたところ、下図のエラーが発生しました。
ビルドエラーとのことなのでログを確認したところ、「nodeのモジュールで足りないものがある」ことと「接続が確立していない」だと読み取りました。
[01:31:52.212] > Build error occurred
[01:31:52.214] Error: Failed to collect page data for /seed
[01:31:52.214] at /vercel/path0/node_modules/.pnpm/next@15.0.0-canary.56_react-dom@19.0.0-rc-f38c22b244-20240704_react@19.0.0-rc-f38c22b24_4ff65fda31da0994155383043ac8ca67/node_modules/next/dist/build/utils.js:1272:15
[01:31:52.215] at process.processTicksAndRejections (node:internal/process/task_queues:105:5) {
[01:31:52.215] type: 'Error'
[01:31:52.215] }
[01:31:52.247] ELIFECYCLE Command failed with exit code 1.
[01:31:52.265] Error: Command "pnpm run build" exited with 1
[01:31:52.587]
Error: Connection terminated unexpectedly
at un.eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:1258:44)
at Object.onceWrapper (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:422:39)
at un.emit (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:409:63)
at x.eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:1210:66)
at x.emit (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:409:63)
at WebSocket.eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:998:51)
at callListener (webpack-internal:///(rsc)/./node_modules/.pnpm/ws@8.14.2_bufferutil@4.0.8_utf-8-validate@6.0.3/node_modules/ws/lib/event-target.js:290:14)
at WebSocket.onClose (webpack-internal:///(rsc)/./node_modules/.pnpm/ws@8.14.2_bufferutil@4.0.8_utf-8-validate@6.0.3/node_modules/ws/lib/event-target.js:220:9)
at WebSocket.emit (node:events:518:28)
at WebSocket.emitClose (webpack-internal:///(rsc)/./node_modules/.pnpm/ws@8.14.2_bufferutil@4.0.8_utf-8-validate@6.0.3/node_modules/ws/lib/websocket.js:260:10)
at TLSSocket.socketOnClose (webpack-internal:///(rsc)/./node_modules/.pnpm/ws@8.14.2_bufferutil@4.0.8_utf-8-validate@6.0.3/node_modules/ws/lib/websocket.js:1272:15)
at TLSSocket.emit (node:events:530:35)
at node:net:337:12
at TCP.done (node:_tls_wrap:657:7)
at TCP.callbackTrampoline (node:internal/async_hooks:130:17)
⨯ node_modules\.pnpm\@neondatabase+serverless@0.7.2\node_modules\@neondatabase\serverless\index.mjs (1244:1) @ un.eval
⨯ uncaughtException: Error: Connection terminated unexpectedly
at un.eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:1258:44)
at Object.onceWrapper (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:422:39)
at un.emit (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:409:63)
at x.eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:1210:66)
at x.emit (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:409:63)
at WebSocket.eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:998:51)
at callListener (webpack-internal:///(rsc)/./node_modules/.pnpm/ws@8.14.2_bufferutil@4.0.8_utf-8-validate@6.0.3/node_modules/ws/lib/event-target.js:290:14)
at WebSocket.onClose (webpack-internal:///(rsc)/./node_modules/.pnpm/ws@8.14.2_bufferutil@4.0.8_utf-8-validate@6.0.3/node_modules/ws/lib/event-target.js:220:9)
at WebSocket.emit (node:events:518:28)
at WebSocket.emitClose (webpack-internal:///(rsc)/./node_modules/.pnpm/ws@8.14.2_bufferutil@4.0.8_utf-8-validate@6.0.3/node_modules/ws/lib/websocket.js:260:10)
at TLSSocket.socketOnClose (webpack-internal:///(rsc)/./node_modules/.pnpm/ws@8.14.2_bufferutil@4.0.8_utf-8-validate@6.0.3/node_modules/ws/lib/websocket.js:1272:15)
at TLSSocket.emit (node:events:530:35)
at node:net:337:12
at TCP.done (node:_tls_wrap:657:7)
at TCP.callbackTrampoline (node:internal/async_hooks:130:17)
1242 | t.ssl?n.requestSsl():n.startup(t.getStartupConf())}),n.on("sslconnect",function(){
1243 | n.startup(t.getStartupConf())}),this._attachListeners(n),n.once("end",()=>{let i=this.
> 1244 | _ending?new Error("Connection terminated"):new Error("Connection terminated unex\
| ^
1245 | pectedly");clearTimeout(this.connectionTimeoutHandle),this._errorAllQueries(i),this.
1246 | _ending||(this._connecting&&!this._connectionError?this._connectionCallback?this.
1247 | _connectionCallback(i):this._handleErrorEvent(i):this._connectionError||this._handleErrorEvent(
⨯ node_modules\.pnpm\@neondatabase+serverless@0.7.2\node_modules\@neondatabase\serverless\index.mjs (1244:1) @ un.eval
⨯ uncaughtException: Error: Connection terminated unexpectedly
at un.eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:1258:44)
at Object.onceWrapper (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:422:39)
at un.emit (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:409:63)
at x.eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:1210:66)
at x.emit (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:409:63)
at WebSocket.eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@neondatabase+serverless@0.7.2/node_modules/@neondatabase/serverless/index.mjs:998:51)
at callListener (webpack-internal:///(rsc)/./node_modules/.pnpm/ws@8.14.2_bufferutil@4.0.8_utf-8-validate@6.0.3/node_modules/ws/lib/event-target.js:290:14)
at WebSocket.onClose (webpack-internal:///(rsc)/./node_modules/.pnpm/ws@8.14.2_bufferutil@4.0.8_utf-8-validate@6.0.3/node_modules/ws/lib/event-target.js:220:9)
at WebSocket.emit (node:events:518:28)
at WebSocket.emitClose (webpack-internal:///(rsc)/./node_modules/.pnpm/ws@8.14.2_bufferutil@4.0.8_utf-8-validate@6.0.3/node_modules/ws/lib/websocket.js:260:10)
at TLSSocket.socketOnClose (webpack-internal:///(rsc)/./node_modules/.pnpm/ws@8.14.2_bufferutil@4.0.8_utf-8-validate@6.0.3/node_modules/ws/lib/websocket.js:1272:15)
at TLSSocket.emit (node:events:530:35)
at node:net:337:12
at TCP.done (node:_tls_wrap:657:7)
at TCP.callbackTrampoline (node:internal/async_hooks:130:17)
1242 | t.ssl?n.requestSsl():n.startup(t.getStartupConf())}),n.on("sslconnect",function(){
1243 | n.startup(t.getStartupConf())}),this._attachListeners(n),n.once("end",()=>{let i=this.
> 1244 | _ending?new Error("Connection terminated"):new Error("Connection terminated unex\
| ^
1245 | pectedly");clearTimeout(this.connectionTimeoutHandle),this._errorAllQueries(i),this.
1246 | _ending||(this._connecting&&!this._connectionError?this._connectionCallback?this.
1247 | _connectionCallback(i):this._handleErrorEvent(i):this._connectionError||this._handleErrorEvent(
原因と対処②
接続エラーなので.envファイルにセットした値とSupabaseの値が合致しているか確認し調査したところ、Supabase側でも環境変数を設定しなければならないことが分かりました。
そこで、以下の方法でSupabase側に環境変数を設定いたしました。
設定値の確認
Supabaseのプロジェクトダッシュボードから Project Settings > Data API を開く。
Data APIの中の「Project URL」の「URL」と「Project API Keys」の「anon
pubilic
」の値をそれぞれメモ帳などに控えます。
又、この設定値はChapter6にて.envファイルに設定したものと同じ(NEXT_PUBLIC_SUPABASE_URLとNEXT_PUBLIC_SUPABASE_API_KEY)であるため、こちらも合わせて確認しましょう。
Environment Variablesへの設定
Vercelのプロジェクトダッシュボードから Settings > Environment Variables を押下する。
「Create new」欄に名前と値をそれぞれセットします。
「NAME」には.envファイルで設定した名称を、「Value」には上述で控えた値をそれぞれセットします。
セットしましたら右下の「Save」ボタンを押下し、「Redeploy」を押下して再度デプロイし直します。
まとめ
非常に長時間かけて苦戦してしまいましたが、何とかNext.jsとSupabaseの連携ができました。
「チュートリアルで扱っているものは例題でも素直に従う」
「チュートリアルで出していることはちゃんと理由がある」
基本中の基本を怠ってしまったことの戒めとして、筆を執らせていただきました。
しかし、「Supabaseというものがある」「Next.jsではデフォルトだとNeonというサービスと連携できるようになっている」ことを学びました。
引き続きチュートリアルを進め、理解を深めて参ります。
参考文献
Next.js のビルド時に Error: Cannot find module '/vercel/path0/node_modules/.pnpm/bcrypt エラーが出たときの対処法
Next.jsチュートリアル
Next.js ✖️ SupabaseプロジェクトのVercelへのデプロイメモ