状況
フロントエンドはNext.js、バックエンドはRailsを用いて開発をしています。
Next.jsのサーバーコンポーネントでバックエンド側にリクエストをする際に、下記のようなエラーが発生しましたので、解決方法について説明したいと思います。
frontend_1 | ⨯ unhandledRejection: TypeError: fetch failed
frontend_1 | at Object.fetch (node:internal/deps/undici/undici:11372:11)
frontend_1 | at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
frontend_1 | cause: Error: connect ECONNREFUSED 127.0.0.1:8080
frontend_1 | at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16)
frontend_1 | at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
frontend_1 | errno: -111,
frontend_1 | code: 'ECONNREFUSED',
frontend_1 | syscall: 'connect',
frontend_1 | address: '127.0.0.1',
frontend_1 | port: 8080
frontend_1 | }
frontend_1 | }
解決策
今回のエラーはNext.js側でサーバーコンポーネントを使ったことに原因がありました。
この場合、二つのサーバーが通信することになりますが、
LocalでのDocker環境で同じローカルホストアドレスを使うと、自分自身にリクエストをかけることになるためエラーになります。
詳細はこちらをご参考ください。https://www.sambaiz.net/article/359/
解決策としては、fetchをする際のURLをhttp://localhost:8080/api/v1/users/1/urls/2
からhttp://backend:8080/api/v1/users/1/urls/2
に修正することです。
※backend
はDockerのサービス名になります。
version: '3.8'
services:
backend:
export default async function getUser() {
const response = await fetch(`http://backend:8080/api/v1/users/1/urls/2`)
if (!response.ok) {
throw new Error('fail')
}
return await response.json()
}
余談
サーバーコンポーネントも単純にもう一つのサーバーであることで、思わぬ所からエラーになりますね。
何時間を調べても解決策がわからなkったのですが、Twitter(X)でエラーが発生して大変だと涙を流してたら、
いろんな方からアドバイスをいただき、解決できました。(ありがとうございます!)
https://x.com/wanchanmask/status/1736378307866919174?s=20
おそらくアドバイスがなかったら解決できなかったと思います。😭
それでは、読んでいただきありがとうございました!