Anugerah Erlaut
Anugerah Erlaut

Reputation: 1130

NextJS use client-side error in custom error page

NextJS renders the custom error page (_error.jsx) when there is client-side UI error. Is it possible to get information on the error inside the custom error page?

I'm using a custom App:

// pages/_app.jsx
import App from 'next/app'

function CustomApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}


CustomApp.getInitialProps = async (props) => {
  { Component, ctx } = props

  const initProps = await Component.getInitialProps(ctx);

  return { pageProps: initProps }
}

export default CustomApp

and I have a page which triggers an error

// pages/throw_error.jsx
function ThrowErrorPage() {
    throw new Error("client-side error")
    ...
}

export default ThrowError

and a custom error page

// pages/_error.jsx
function Error(props) {
  
   // Expecting error from the UI
   const { err } = props;
  
   return (
      <div>{err.message}</div>
   )
}

Error.getInitialProps = async (props) => {
   const { err } = props;
   const statusCode = res ? res.statusCode : err ? err.statusCode : 404;
   return { err, statusCode };
}

export default Error

I was expecting err to be passed from the UI to _error.jsx. Am I missing something?

Upvotes: 1

Views: 5184

Answers (1)

Anugerah Erlaut
Anugerah Erlaut

Reputation: 1130

So it turns out that NextJS does return client-side error to the custom error component. When a client-side error occurs, NextJS fetches the custom _error.jsx [1], and passes it as the value of the Component to the custom App (_app.jsx), along with a ctx object which contains the error object err [2]. In the custom App, we can then pass the error object to the error component as a prop, and extract it in the component for display/logging:

First pass the error object in the custom app to the component where the error is going to be rendered:

// pages/_app.jsx
import App from 'next/app'

function CustomApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

CustomApp.getInitialProps = async (props) => {
  { Component, ctx : { err } } = props;
  
  // Return early if there is an error 
  // pass the error to the component
  if (err) return { pageProps : { err } };

  const componentProps = await Component.getInitialProps(ctx);

  return { pageProps: { ...componentProps } };
}

export default CustomApp;

Then extract the error object from the component's prop

// pages/_error.jsx
function Error({ err }) {
   logToService(err)
   return err.message;
}

export default Error;

Upvotes: 4

Related Questions