Skip to main content

How to send a custom response by throwing an error and catching it

This method is useful in case you want to send a custom response from an overrided function which doesn't have access to the response object. This can happen in case you are overriding any of our recipe interface functions.

Let's take an example in which we want to prevent a user from logging into a new device if a session already exists for them in another device. We also want to send a custom response from the API in case we are preventing a login. For this, we will be overriding the createNewSession function from the Session recipe.

In the override, we will check if a session already exists for the given userId, and if it does, we will throw an error from the function. This error will be propogated to your application's error handler (or an error handler callback if you have provided one to us), in which you can catch this and send a custom response.

Step 1#

First, we override the createNewSession function and throw an error in case a session already exists for a user. We can do this in the Session.init function:

import Session from "supertokens-node/recipe/session";

Session.init({
override: {
functions: (originalImplementation) => {
return {
...originalImplementation,
createNewSession: async function (input) {
const existingSessions = await Session.getAllSessionHandlesForUser(input.userId);
if (existingSessions.length > 0) {
// this means that the user already has a session on some other device
throw new Error("Session already exists on another device");
}

// no other session exists, and so we can continue with logging in this user
return originalImplementation.createNewSession(input);
}
}
}
}
})

Step 2#

Next, we want to catch the thrown error and then send a custom response to the client

import express from "express";

let app = express();

//...

// in your app's error handler, we catch the custom error
app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
if (err.message === "Session already exists on another device") {
// TODO: send a custom response using res
return;
}
res.send(500).send(err.message)
})
Which UI do you use?
Custom UI
Pre built UI