Custom error response using GENERAL_ERROR
status
Sometimes, you may want to send a custom error message from your API override to display to the user on the frontend. This can be done by sending the following JSON response from the API:
{
"status": "GENERAL_ERROR",
"message": "Some custom error message"
}
If you are using our pre-built ReactJS UI, the above response will render the mesage "Some custom error message"
on the frontend UI. For custom UI, you can read this response and display the message in an error UI. This response can be returned from most of the APIs exposed by the backend SDK.
Let's take an example in which we want to prevent the user from signing up unless their email is preapproved by the app's admin. For this, we will override the sign up API to check if the input email is approved or not, and if not, we prevent the sign up, and send a custom error message.
- NodeJS
- GoLang
- Python
- Other Frameworks
Important
import Passwordless from "supertokens-node/recipe/passwordless";
Passwordless.init({
contactMethod: "...",
override: {
apis: (oI) => {
return {
...oI,
consumeCodePOST: async function (input) {
let codesInfo = await Passwordless.listCodesByPreAuthSessionId({
tenantId: input.tenantId,
preAuthSessionId: input.preAuthSessionId
})
let email = codesInfo?.email!
if (emailNotAllowed(email)) {
return {
status: "GENERAL_ERROR",
message: "You are not allowed to sign up. Please contact the app's admin to get permission"
}
}
return oI.consumeCodePOST!(input);
}
}
}
}
})
function emailNotAllowed(email: string) {
// TODO: your impl to check if email is allowed or not
return true;
}
import (
"github.com/supertokens/supertokens-golang/recipe/passwordless"
"github.com/supertokens/supertokens-golang/recipe/passwordless/plessmodels"
"github.com/supertokens/supertokens-golang/supertokens"
)
func main() {
passwordless.Init(plessmodels.TypeInput{
Override: &plessmodels.OverrideStruct{
APIs: func(originalImplementation plessmodels.APIInterface) plessmodels.APIInterface {
ogConsumeCodePOST := *originalImplementation.ConsumeCodePOST
(*originalImplementation.ConsumeCodePOST) = func(userInput *plessmodels.UserInputCodeWithDeviceID, linkCode *string, preAuthSessionID string, tenantId string, options plessmodels.APIOptions, userContext supertokens.UserContext) (plessmodels.ConsumeCodePOSTResponse, error) {
codeInfo, err := passwordless.ListCodesByPreAuthSessionID(tenantId, preAuthSessionID)
if err != nil {
return plessmodels.ConsumeCodePOSTResponse{}, err
}
email := *codeInfo.Email
if emailNotAllowed(email) {
return plessmodels.ConsumeCodePOSTResponse{
GeneralError: &supertokens.GeneralErrorResponse{
Message: "You are not allowed to sign up. Please contact the app's admin to get permission",
},
}, nil
}
return ogConsumeCodePOST(userInput, linkCode, preAuthSessionID, tenantId, options, userContext)
}
return originalImplementation
},
},
})
}
func emailNotAllowed(email string) bool {
// TODO: your impl to check email
return true
}
from supertokens_python.recipe import passwordless
from supertokens_python.recipe.passwordless.interfaces import APIOptions
from supertokens_python.recipe.session.interfaces import SessionContainer
from typing import Dict, Any, Union, Optional
from supertokens_python.recipe.passwordless.interfaces import APIInterface
from supertokens_python.recipe.passwordless.asyncio import (
list_codes_by_pre_auth_session_id,
)
from supertokens_python.types import GeneralErrorResponse
def override_passwordless_apis(original_implementation: APIInterface):
original_consume_code_post = original_implementation.consume_code_post
async def consume_code_post(
pre_auth_session_id: str,
user_input_code: Union[str, None],
device_id: Union[str, None],
link_code: Union[str, None],
session: Optional[SessionContainer],
should_try_linking_with_session_user: Union[bool, None],
tenant_id: str,
api_options: APIOptions,
user_context: Dict[str, Any],
):
code_info = await list_codes_by_pre_auth_session_id(
tenant_id, pre_auth_session_id
)
if code_info is None:
raise Exception("Should never come here")
email = code_info.email
if email is None:
# this example is focused on login via email
raise Exception("Should never come here")
if is_not_allowed(email):
return GeneralErrorResponse(
"You are not allowed to sign up. Please contact the app's admin to get permission"
)
return await original_consume_code_post(
pre_auth_session_id,
user_input_code,
device_id,
link_code,
session,
should_try_linking_with_session_user,
tenant_id,
api_options,
user_context,
)
original_implementation.consume_code_post = consume_code_post
return original_implementation
def is_not_allowed(email: str):
# TODO: your impl to check if the email is allowed
return True
passwordless.init(
override=passwordless.InputOverrideConfig(apis=override_passwordless_apis),
)