Skip to content
Esc
navigateopen⌘Jpreview
Dashboard
On this page

Customize error handling

Customize errors thrown by the Session recipe in your SuperTokens integration.

Overview

The following page shows the errors that the SuperTokens Session recipe throws and how you can customize them.


Unauthorised error

The system generates the error when someone accesses a protected backend API without a session. The default behavior is to clear session tokens (if any) and send a 401 to the frontend.

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

SuperTokens.init({
  supertokens: {
    connectionURI: "...",
  },
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    Session.init({
      errorHandlers: {
        onUnauthorised: async (message, request, response, userContext) => {
          // TODO: Write your own logic and then send a 401 response to the frontend
        },
      },
    }),
  ],
});
import (
	"net/http"

	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			session.Init(&sessmodels.TypeInput{
				ErrorHandlers: &sessmodels.ErrorHandlers{
					OnUnauthorised: func(message string, req *http.Request, res http.ResponseWriter) error {
						// TODO: Write your own logic and then send a 401 response to the frontend
						return nil
					},
				},
			}),
		},
	})
}
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import session
from supertokens_python.framework import BaseRequest, BaseResponse

async def unauthorised_callback(req: BaseRequest, err: str, response: BaseResponse):
    # TODO: Write your own logic and then send a 401 response to the frontend
    return response

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        session.init(
            error_handlers=session.InputErrorHandlers(
                on_unauthorised=unauthorised_callback
            )
        )
    ]
)

Invalid claim error

The system generates the error when someone accesses a protected backend API with a session that doesn’t pass the claim validators. The default behavior is to send a 403 to the frontend with the errors included in the body.

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

SuperTokens.init({
  supertokens: {
    connectionURI: "...",
  },
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    Session.init({
      errorHandlers: {
        onInvalidClaim: async (validatorErrors, request, response, userContext) => {
          // TODO: Write your own logic and then send a 403 response to the frontend
        },
      },
    }),
  ],
});
import (
	"net/http"

	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/recipe/session/claims"
	"github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			session.Init(&sessmodels.TypeInput{
				ErrorHandlers: &sessmodels.ErrorHandlers{
					OnInvalidClaim: func(validationErrors []claims.ClaimValidationError, req *http.Request, res http.ResponseWriter) error {
						// TODO: Write your own logic and then send a 403 response to the frontend
						return nil
					},
				},
			}),
		},
	})
}
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import session
from supertokens_python.recipe.session.exceptions import ClaimValidationError
from supertokens_python.framework import BaseRequest, BaseResponse
from typing import List

async def invalid_claim_callback(req: BaseRequest, invalid_claims: List[ClaimValidationError], response: BaseResponse):
    # TODO: Write your own logic and then send a 403 response to the frontend
    return response

init(
    app_info=InputAppInfo(
        api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        session.init(
            error_handlers=session.InputErrorHandlers(
                on_invalid_claim=invalid_claim_callback
            )
        )
    ]
)

Token theft detected error

The system generates the error when the system detects a session hijacking attempt. This happens through the use of rotating refresh tokens. The default behavior is to revoke the session and send a 401 to the frontend.

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

SuperTokens.init({
  supertokens: {
    connectionURI: "...",
  },
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    Session.init({
      errorHandlers: {
        onTokenTheftDetected: async (sessionHandle, userId, req, res, userContext) => {
          // TODO: Write your own logic and then send a 401 response to the frontend
        },
      },
    }),
  ],
});
import (
	"net/http"

	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			session.Init(&sessmodels.TypeInput{
				ErrorHandlers: &sessmodels.ErrorHandlers{
					OnTokenTheftDetected: func(sessionHandle, userID string,
						req *http.Request, res http.ResponseWriter) error {
						// TODO: Write your own logic and then send a 401 response to the frontend
						return nil
					},
				},
			}),
		},
	})
}
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import session
from supertokens_python.framework import BaseRequest, BaseResponse
from supertokens_python.types import RecipeUserId

async def token_theft_detected_callback(req: BaseRequest, session_handle: str, user_id: str, recipe_user_id: RecipeUserId, response: BaseResponse):
    # TODO: Write your own logic and then send a 401 response to the frontend
    return response

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),

    framework='...',
    recipe_list=[
        session.init(
            error_handlers=session.InputErrorHandlers(
                on_token_theft_detected=token_theft_detected_callback
            )
        )
    ]
)

Try refresh token error

Thrown when the access token expires or is invalid. The session refresh endpoint can also throw this if multiple access tokens are present in the request cookies. The default behavior is to send a 401 to the frontend.

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

SuperTokens.init({
  supertokens: {
    connectionURI: "...",
  },
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    Session.init({
      errorHandlers: {
        onTryRefreshToken: async (message, request, response, userContext) => {
          // TODO: Write your own logic and then send a 401 response to the frontend
        },
      },
    }),
  ],
});
import (
	"net/http"

	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			session.Init(&sessmodels.TypeInput{
				ErrorHandlers: &sessmodels.ErrorHandlers{
					OnTryRefreshToken: func(message string, req *http.Request, res http.ResponseWriter) error {
						// TODO: Write your own logic and then send a 401 response to the frontend
						return nil
					},
				},
			}),
		},
	})
}
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import session
from supertokens_python.framework import BaseRequest, BaseResponse

async def try_refresh_callback(req: BaseRequest, err: str, response: BaseResponse):
    # TODO: Write your own logic and then send a 401 response to the frontend
    return response

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        session.init(
            error_handlers=session.InputErrorHandlers(
                on_try_refresh_token=try_refresh_callback
            )
        )
    ]
)

Clear duplicate session cookies error

Thrown when the refresh session API clears session cookies from the olderCookieDomain because it found multiple access tokens in the request cookies. See this issue for more information. The default behavior is to send a 200 to the frontend.

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

SuperTokens.init({
  supertokens: {
    connectionURI: "...",
  },
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    Session.init({
      errorHandlers: {
        onClearDuplicateSessionCookies: async (message, request, response, userContext) => {
          // TODO: Write your own logic and then send a 200 response to the frontend
        },
      },
    }),
  ],
});
import (
	"net/http"

	"github.com/supertokens/supertokens-golang/recipe/session"
	"github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			session.Init(&sessmodels.TypeInput{
				ErrorHandlers: &sessmodels.ErrorHandlers{
					OnClearDuplicateSessionCookies: func(message string, req *http.Request, res http.ResponseWriter) error {
						// TODO: Write your own logic and then send a 200 response to the frontend
						return nil
					},
				},
			}),
		},
	})
}
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import session
from supertokens_python.framework import BaseRequest, BaseResponse

async def on_clear_duplication_session_cookies_callback(req: BaseRequest, err: str, response: BaseResponse):
    # TODO: Write your own logic and then send a 200 response to the frontend
    return response

init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...',
    recipe_list=[
        session.init(
            error_handlers=session.InputErrorHandlers(
                on_clear_duplicate_session_cookies=on_clear_duplication_session_cookies_callback
            )
        )
    ]
)

API reference

API schema and response details