Dealing with errors in getServerSideProps in Next.js by utilizing next-connect

Recently, I've been working with Next.js and utilizing the next-connect library to manage middlewares in my project.

However, I'm encountering some difficulties when it comes to handling errors while using multiple middlewares within the getServerSideProps function.

The code snippet below showcases how I have set up my middleware handler within getServerSideProps. The goal is for each middleware to execute successfully, retrieve user data upon authentication, but if any middleware fails, an error should be caught and a redirect to the '/login' page should occur:

import nextConnect from 'next-connect';
import { openDBConnection, retrieveUserInfo } from '@/middlewares/database';
import { verifySessionCookie } from '@/middlewares/firebaseSession';
...
    export const getServerSideProps = async ({ req, res }) => {
        const handler = nextConnect()
            .use(verifySessionCookie)
            .use(openDBConnection)
            .use(retrieveUserInfo);
        try {
            await handler.run(req, res);
            return {
                props: {
                    user: req.user,
                },
            };
        } catch (e) {
            console.log(e);
            return {
                redirect: {
                    destination: '/login',
                    permanent: false,
                }
            };
        }
    }

Although no try/catch blocks are defined within the individual middlewares, any errors that arise should ideally be handled within the api pages or the main getServerSideProps block.

Initially, everything worked fine with just one middleware (verifySessionCookie). Errors were properly caught when calling await handler.run(req, res) and handled in the catch block. However, the issue arises when incorporating all 3 middlewares as displayed in the code snippet. If the first middleware (verifySessionCookie) encounters an error, it does not trigger the catch block.

I've attempted implementing a next() call in each middleware, along with a finally clause, which did allow for error handling within getServerSideProps. Unfortunately, scenarios where one middleware fails, causing subsequent ones to not execute as intended, remain problematic.

  • verifySessionCookie executes and fails.
  • openDBConnection executes without issues.
  • retrieveUserInfo executes and fails.

At this point, I'm uncertain whether I'm making mistakes in my approach or if next-connect isn't designed for this specific use case. Perhaps resorting to individual asynchronous functions with (req, res) parameters directly inside getServerSideProps could be a viable alternative, rather than relying on the next-connect plugin.

Answer №1

According to the next-connect documentation, you have the ability to include onError in your nextConnect.

function onError(err, req, res, next) {
  logger.log(err);

  res.status(500).end(err.toString());
  // OR: you may want to continue
  next();
}

const handler = nextConnect({ onError });

You can also customize values by passing them with req in your middleware.

In your middleware, utilize a try/catch block to accommodate different values with req:

export const middlewareExample = (req, res, next) => {
  try {
    // ...
    req.condition = {
      status: 'success, ...',
      message: '...',
      data: {
        // ...
      }
    }
    next();
  } catch(error) {
    res.status(...).end(...);
    // OR: you may want to continue
    req.condition = {
      status: 'error, ...',
      message: '...',
      data: {
        // ...
      }
    }
    next();
  }
}
export const getServerSideProps = async ({ req, res }) => {
  const handler = nextConnect()
  .use(verifySessionCookie)
  .use(openDBConnection)
  .use(retrieveUserInfo);

  await handler.run(req, res);

  if (req.condation.status === 'success') {
    return {
      props: {
        user: req.user,
      },
    };
  } else {
    console.log(req.condation.message);
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      }
    };
  }
})

This information should be beneficial for your integration.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the feature of On Demand Cache Revalidation in Next JS 13 with a remote ASP .NET Core backend

Seeking guidance on leveraging NextJS cache revalidation for a specific use case that seems unique. Currently, I am in the process of developing an online food ordering platform where numerous restaurants (currently 30) can publish their menus for customer ...

Tips on how to show a personalized <Errormessage> within a Formik field component while turning off the standard message

In my current web project, I am utilizing a combination of React, Material-UI, Formik, and formik-material-ui. Specifically, I have implemented a Formik form that includes validation using yup. const schema = yup.object({ name: yup.string().trim().low ...

The app bar menu items are failing to open the appropriate submenus in a correct

I am in the process of developing a frontend application using React16 along with the Material UI library. My current task involves creating a navigation bar at the top that contains multiple menu items. For this, I referred to the "simple menu" example o ...

"Utilizing multiple class names in Next.js to enhance website styling

Looking for a way to apply multiple classNames in Next.js, especially when dealing with variable classnames? I'm following the component level CSS approach. Take a look at my code and what I aim to achieve: import styles from "./ColorGroup.mod ...

Error encountered: "Jest error - TypeError: Unable to access property 'preventDefault' because it is undefined."

I encountered an issue while testing the function below, resulting in the error mentioned above. function toggleRecovery = e => { e.preventDefault() this.setState( { recovery: !this.state.recovery }, () => { ...

How can I personalize the color of a Material UI button?

Having trouble changing button colors in Material UI (v1). Is there a way to adjust the theme to mimic Bootstrap, allowing me to simply use "btn-danger" for red, "btn-success" for green...? I attempted using a custom className, but it's not function ...

When using React.js with Leaflet, ensure that the useEffect hook is only run on Mount when in the

I have encountered an issue where I need to ensure that the useEffect Hook in React runs only once. This is mainly because I am initializing a leaflet.js map that should not be initialized more than once. However, anytime I make changes to the component&a ...

Refresh the React state at regular intervals

constructor(){ super(); this.state={ numbers : [1,2,3,4,1,2,3,4,1,3,1,4,12,2,3,2] }; } componentDidMount(){setInterval(this.updateNumbers(),5000);} updateNumbers() { console.log(this.props.newData); let numbers = this.state.nu ...

How to correctly pass a function between components in React using TypeScript

Having just started learning typescript, I encountered difficulties passing a function from the parent component to another component as a prop. Despite searching online for solutions, I couldn't find anything helpful. Here is the JSX Code for refere ...

Having trouble getting z-index to work in Material-UI with ReactJS? Need to showcase an element on top of others?

I'm having trouble displaying a Box component above a Modal component. Both components are from Material UI. Within the structure, there is a Parent Box component containing another Box component. My goal is to have the second/child Box component ap ...

Error TS2307: Module './tables.module.css' or its type declarations could not be located

Currently utilizing CSS modules within a create-react-app project and encountering an error within Google Chrome browser: https://i.stack.imgur.com/0ItNM.png However, the error appears to be related to eslint because I am able to close the warning modal i ...

Tips for incorporating dynamic content into React Material UI expansion panels while maintaining the ability to have only one tab active at a time

I'm working on a project using WebGL and React where I generate a list of users from mock data upon clicking. To display this content in an accordion format, I decided to use Material UI's expansion panel due to my positive past experience with ...

Tips for changing the TextField variant when it receives input focus and keeping the focus using Material-UI

When a user focuses on the input, I'd like to change the variant of the TextField. The code snippet below accomplishes this, but the input loses focus. This means the user has to click again on the input to focus and start typing. import React, { useS ...

Setting up Emotion js in a React TypeScript project using Vite 4

Currently, I am in the process of transitioning from Webpack to Vite for my React Typescript application. I have been attempting to integrate Emotion js into the project. "@vitejs/plugin-react": "^4.0.1", "vite": "^4.3.9 ...

Redux - Refreshing the subtree state

How can I properly reset the subtree of a redux store without resetting the entire store? I want to target only the reducer subtree in question. Check out this example code: //initial state const initialState = { isFetching: false, error: '& ...

I am planning to divide my web application into two sections by utilizing react router. I intend to incorporate a router within one of the routes mentioned earlier

/src |-- /components | |-- /signin | |-- SignIn.js | |-- /home | |-- Home.js | | |-- /dashboard | |-- Dashboard.js | |-- /assignee |-- /App.js |-- /index.js Dividing the project into two main parts: signi ...

TypeScript version 3.7 has implemented a new feature where it will now display errors for each individual invalid prop instead of grouping them together as it

Scenario using TypeScript 3.5.3 https://i.stack.imgur.com/wykd6.png link to interactive playground - TS 3.5.3 demo running successfully Example with TypeScript 3.7.2 https://i.stack.imgur.com/BPckB.png link to demo - TS 3.7.2 demo not functioning correctl ...

Notify user when Redux action is completes in ReactJS/Redux application

I've been working on a custom notification component that should display a message and then hide itself after a few seconds when certain redux actions, like login_fail, are triggered. However, I'm facing an issue where the message briefly pops up ...

Having trouble compiling Typescript code when attempting to apply material-ui withStyles function

I have the following dependencies: "@material-ui/core": "3.5.1", "react": "16.4.0", "typescript": "2.6.1" Currently, I am attempting to recreate the material-ui demo for SimpleListMenu. However, I am encountering one final compile error that is proving ...

Tips on modifying the border, text color, and border color of Material-UI TextField when hovered over

I'm struggling to grasp the concept of customizing MaterialUI components. Although I have read through the documentation at https://material-ui.com/customization/components/ on how to customize using classes and className, I am still finding the advan ...