Deliver a personalized error notification using serverless-http (express) framework

I am trying to send a custom error message in JSON format from my express app, which is served in a lambda function using serverless-http

To achieve this, it seems I need to utilize LAMBDA_PROXY APIG integration to enable sending custom error messages directly from a lambda function.

Here's what I have attempted so far:

res.status(400).json({ message: 'email already taken' });

In the serverless.yml file, I have configured the following:

functions:
  auth:
    handler: src/express/auth/index.handler
    name: ${self:service}-auth-${env:STAGE}
    # warmup: true
    integration: lambda-proxy
    memorySize: 128
    timeout: 15
    events:
        - http:
            path: /auth/
            method: ANY
            cors: true
        - http:
            path: /auth/{any+}
            method: ANY
            cors: true

This is the response returned by the API (with status code 400):

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Error</title>
    </head>
    <body>
        <pre>Bad Request</pre>
    </body>
</html>

Can anyone provide guidance on how I can send a custom response in JSON format?

Update: After further testing, I noticed that calling next(error) does not trigger the last error handler


const register = async (req, res, next) {
  try {
    await verifyEmail(req.body.email);
    const user = await Users.register(req.body);
    const token = sign(user.attrs, {});
    res.json({ token, user });
  } catch (e) {
    next(e);
  }
};

const generalError = async (err, req, res, next) => {
  // This part is not reached! :(
  console.log('generalError handler', JSON.stringify(err));
  res.status(errorOut.status).json(errorOut);
};

ApiRouter.post('/register', register);
app.use('/auth', ApiRouter);
app.use(generalError);

Answer №1

(I recently provided a solution to a similar question here)

A helpful explanation can be found in the Express documentation under Error Handling.

Express is equipped with an internal error handler that addresses any errors that may arise within the application. This default error-handling middleware function is positioned at the end of the middleware function stack.

If an error is passed to next() and no custom error handler is in place, it will be managed by the built-in error handler; this error will be displayed to the client along with the stack trace. However, the stack trace is not exhibited in the production environment.

To replace this handler, consult the section in the Express docs labeled Writing error handlers.

This section explains:

Error-handling middleware functions are defined similarly to other middleware functions, but error-handling functions include four arguments instead of three: (err, req, res, next). For instance:

app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})

Error-handling middleware should be defined last, after other app.use() and route calls

In your scenario, if you wish to return a 400 status code and some JSON data, consider implementing something like the following:

const serverless = require('serverless-http');
const express = require('express');
const app = express();

// Include your middleware and additional routes here
app.use(/* register your middleware as normal */);

// Lastly, implement your custom error handler
app.use(function customErrorHandler(err, req, res, next) {
   res.status(400).json({ message: 'email already taken' });
});

module.exports.handler = serverless(app);

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

`Node.JS app having issue displaying AngularJS code on Localhost`

I have successfully created a Node.JS application, where I implemented my own HTTP server within the main JS file. The HTML and CSS render correctly on localhost, and even JQuery works when imported via CDN. However, I am facing an issue with displaying ba ...

Failure to trigger callback in passport-amazon module

Currently, I have implemented a passport-amazon strategy on an express server route. Below are the key sections of the code: The passport initialization in server.js looks like this: //configure passport app.use(passport.initialize()); app.use(passport.s ...

Is it possible to upload an image-containing object to Mongodb with the help of Node.js?

I am struggling to upload an object containing an image to the mongodb database using Node.js. Angular File onSelectedFile(event){ this.edit_image = event.target.files[0]; } editProfile(e){ const user={ email:this.edit_email, img:this.edit_imag ...

Utilizing Axios: Maintaining session continuity post successful authorization and including it in subsequent requests - testing in a browser-less environment

During this test scenario, I am sending an axios post request to an ExpressJS server that is running with passportjs local. The request includes a userId and password, and the server responds with a status code of 200, along with setting an appropriate hea ...

Having trouble locating the express module in your node application?

I am facing an issue that I can't seem to pinpoint the cause of, even though everything should be functioning properly. According to npm, I have express installed: C:\Users\phucker\Desktop>node init.js module.js:340 throw err; ...

Is there a way to implement personalized error management in TypeScript with Express?

For a while now, I have been using JavaScript to create my APIs but recently made the switch to TypeScript. However, I keep encountering errors along the way. One particular error handler I have set up is for when a route cannot be found, as shown below: i ...

Guide to building a seamless page without refreshes with the help of jquery, express, and handlebars

I need assistance with my express JS project. I am trying to set up two pages using NodeJS, incorporating handlebars as the template engine. My objective is to have the first page rendered using res.render('home'), and for the second page to be l ...

EJS template variable inventory

I'm currently utilizing espress.js in combination with the ejs template engine. My goal is to retrieve a collection of variables that are being passed to the view... Below is an example of a controller: homeAction(req, res) { res.re ...

Using multiple middlewares in ExpressJS to connect to callbacks

I have a custom ExpressJS application that processes form data in several steps: First, it checks if all the required values are provided. Next, it validates the data to ensure its accuracy. Then, it generates a unique ID by adding a record to the databas ...

"Using nginx to proxy a Node.js Express application running on a remote server within a sub

I am facing a challenge where I need to host multiple node applications on a single server. To achieve this, I have set up the applications to run on different ports and can access them by specifying the IP address along with the respective port numbers. ...

Communication breakdown with Terraform API Gateway pre-flight OPTIONS requests

My AWS API Gateway REST API is integrated with Lambda Proxy using Terraform. The Lambdas handle CRUD operations on a DynamoDB table, and Cognito User Pool Authorizer is configured for all requests except for `GET` or `OPTIONS`. I've set up the `OPTIO ...

Adding a new element to a JSON file in MongoDB: A simple guide

I have a straightforward inquiry, but my English skills are not the best for articulating it clearly. Let me provide an example to illustrate: Suppose we have a MongoDB object structured as follows: {_id:ObjectId("606445724bd1552e94f60691"),email ...

Refreshing the page or directly loading it results in a blank screen being displayed

Despite researching various solutions to this common issue, none seem to work for me. Let's dive into it. I've developed a Vue 2 application integrated with Express running on AWS Amplify. When testing the app locally in 'dev' mode (np ...

The issue with Postman Express.js Response Body not displaying any content is quite common

I've been struggling with this issue for a whole day and I just can't seem to find a solution. My node app is extremely simple. const express = require("express"); const port = 3001; const app = express(); app.use(express.json()); app.pos ...

Establishing the Session Once Headers are Established

Currently, I am working on implementing an asynchronous method that involves making a POST call to a specific API to fetch data and then storing the result in the user's session. Although the task itself seems straightforward, it becomes challenging w ...

Leveraging bodyparser for executing bulk updates on multiple rows in Postgres database

My web application is created using Express and Postgres. To update a single product in my table, I use the following query: const sqlProdOrder = 'UPDATE product_index SET product_ordered = $2 WHERE product_id = $1'; Now, I am attempting to up ...

The Node.js application is unable to locate the source file path

Currently, I am in the process of creating a simple quiz application. While working on this project, I encountered an issue with linking a JS file in an HTML template. Even though I have confirmed that the path is correct, every time I run my node app, the ...

Configuring CORS to Allow Credentials and Preflight Requests in a Node/Express Application

Among the plethora of CORS questions out there, I seem to be struggling with a particular issue. Despite my decent understanding of CORS and going through numerous posts, I am still stuck on getting my (Node/Express) API to function on a real URL without u ...

Connecting user information across various passport strategies

Currently, I am utilizing node, express, express-session, mongoose, and passport-discord for user authentication. However, I am also interested in incorporating passport-steam to give users the option to link their steam account to their discord account. ...

Error: Document's _id field cannot be modified

I am new to both MongoDB and Backbone, and I find it challenging to grasp the concepts. My main issue revolves around manipulating attributes in Backbone.Model to efficiently use only the necessary data in Views. Specifically, I have a model: window.User ...