[TIL] Next.js는 server action에서의 try catch를 추천하지 않는다.

기성·2024년 10월 23일
0

TIL

목록 보기
74/81

최종 프로젝트를 진행하면서 유저 정보를 가져올 때 유저 정보가 없을시의 에러처리를 어떻게 처리할지 고민하는 도중에 Next.js의 docs에서 server action에서 try catch를 추천하지 않는다고 하는 것을 보게 되었다.

Error Handling

본문에 따르면 에러는 예상되는 에러와 잡히지 않는 예외상황 두 가지로 나눌 수 있다고한다.

  • 예상 에러를 반환값으로 모델링해라: server action에서 예상되는 에러에 try/catch문을 사용하지마라. 대신 useFormState를 사용해라.
  • 예기치 못한 에러에는 에러 바운더리를 사용해라. : 예상치 못한 에러에는 error.tsx와 global-error.tsx를 사용해서 에러 바운더리를 구현하여 예상치 못한 에러를 fallback ui를 통해 제공해라.

Handling Expected Errors from Server Actions

예상되는 에러처리는 서버사이드에서의 form 유효성 검사 또는 요청 실패와 같이 어플리케이션의 정상적인 작동 중 발생할 수 있는 오류인데 이런 오류는 명시적으로 처리해서 클라이언트에 반환을 해야한다고 한다.

예시)

'use server'
 
import { redirect } from 'next/navigation'
 
export async function createUser(prevState: any, formData: FormData) {
  const res = await fetch('https://...')
  const json = await res.json()
 
  if (!res.ok) {
    return { message: 'Please enter a valid email' }
  }
 
  redirect('/dashboard')
}

에러처리를 포함해서 서버 작업 상태를 관리할 때는 useFormState훅을 사용하고 이 접근 방식은 try/catch문을 사용하지 않고 예외처리가 아닌 에러를 return해주는 식으로 모델링해야한다.

'use client'
 
import { useFormState } from 'react'
import { createUser } from '@/app/actions'
 
const initialState = {
  message: '',
}
 
export function Signup() {
  const [state, formAction] = useFormState(createUser, initialState)
 
  return (
    <form action={formAction}>
      <label htmlFor="email">Email</label>
      <input type="text" id="email" name="email" required />
      {/* ... */}
      <p aria-live="polite">{state?.message}</p>
      <button>Sign up</button>
    </form>
  )
}

이후 useFormState에 action을 통과시키고 state를 return받아서 error 메세지를 출력한다. 이 방식으로 taost message또한 display할 수 있다.

Handling Expected Errors from Server Components

export default async function Page() {
  const res = await fetch(`https://...`)
  const data = await res.json()
 
  if (!res.ok) {
    return 'There was an error.'
  }
 
  return '...'
}

서버 컴포넌트에서도 data를 fetching할 때 response에 조건부로 에러 메세지나 redirect를 return하는 것을 추천하고 있다.

본문을 보니까 우리가 예측할 수 있는 에러들은 클라이언트 상에서 따로 메세지를 보여주도록 하거나 redirect를 하는 방향을 추천을 하고 있고 예상치 못한 에러일 경우에만 에러 바운더리에서 error.tsx나 global-error.tsx같은 fallback ui를 통해 처리하는 것을 의도하는 것 같다.

에러처리 참 어렵다... 어떤 에러들을 명시적으로 처리해야할지도 기획 단계에서 해야 에러처리가 쉬운 방향일 것 같다. 명시적으로 넘겨서 처리할 수 있는 것들은 굳이 error boundary로 넘길 필요가 없는 것일까? 만약 server action에서 에러를 throw한다면 error boundary로 넘어갈 것이고 여기서 reset과 refresh를 했을 때 try catch가 이를 방해 할 수 도 있고 중복된 에러처리가 될 수도 있어서 그런 것 같기도 하다.

profile
프론트가 하고싶어요

0개의 댓글