How to throw an exception with a status code?
Asked Answered
P

8

42

How can throw an error with options or a status code and then catch them?

From the syntax here, it seems we can through the error with additional info:

new Error(message, options)

So, can we throw like this below?

throw new Error('New error message', { statusCode: 404 })

Then, how can we catch that statusCode?

try {
 //...
} catch (e) {
  console.log(e.statusCode) // not working off course!
}

Any ideas?


Options are not supported yet.

Re-throw the error works:

try {
  const found = ...

  // Throw a 404 error if the page is not found.
  if (found === undefined) {
    throw new Error('Page not found')
  }

} catch (error) {
  // Re-throw the error with a status code.
  error.statusCode = 404
  throw error
}

but it is not an elegant solution.

Pagel answered 13/9, 2021 at 16:6 Comment(7)
"From the syntax here, it seems we can through the error with additional info:" the page then describes what options should look like. It can include a cause.Sayre
Why do you need to throw Error specifically and not anything else?Sayre
Either make a custom error subclass that takes a second argument, or use throw Object.assign(new Error('New error message'), { statusCode: 404 });Eparchy
"Options are not supported yet." 1. there is literally a single option you can use. Not arbitrary options. 2. The option(s) is supported but only in the latest Chrome/FF/Safari caniuse.com/…Sayre
"My solution is to re-throw the error:" why? That's worse than using a try/catch as control flow. Because there is no control, it's linear. Why not create the error, add the property then throw it, instead of create -> throw -> add property -> rethrow? I do not understand what you want to happen here. What solution exactly are you looking for, why the roundaboundness of this all?Sayre
As asked, it's not really clear what you want, but it's clear that you've misunderstood what options is for: It's not for passing arbitrary key/value pairs like status: "404", it's for passing cause: "<something>". Regardless of support, you can't use it to pass arbitrary data around with your exceptions. You have two answers below that will allow you to do this, and you've rejected them both, one because you want it "shorter" and one because you don't want to use custom errors for some reason. Please clarify your requirements.Zoo
Please stop abusing the flagging system to level "harassment/bigotry/abuse" flags at people trying to suss out details from you. Nobody here is harassing you, we're trying to understand what you want, and to help clarify your own misunderstanding of the options parameter.Zoo
M
44

You can use err.code

const error = new Error("message")
error.code = "YOUR_STATUS_CODE"
throw error;
Mum answered 13/9, 2021 at 16:26 Comment(1)
I have thought of that too. I am trying to reduce these 3 lines to make it shorter.Pagel
S
8

as described here you have to create a custom exception for this:

function CustomException(message) {
  const error = new Error(message);

  error.code = "THIS_IS_A_CUSTOM_ERROR_CODE";
  return error;
}

CustomException.prototype = Object.create(Error.prototype);

then you can throw your custom exception:

throw new CustomException('Exception message');
Selfgoverned answered 13/9, 2021 at 16:18 Comment(3)
Why set the prototype if it's not used at all?Sayre
But don't do it like that. Either use factory function (no new!) that returns an Error instance with a custom property, or use a class that extends Error and use it with new.Eparchy
I have seen that. thanks. I am trying to reduce from making a custom error. But i think the internal options are not supported yet.Pagel
T
4
class CustomError extends Error {
 constructor(message, statusCode) {
  super(message)
  this.statusCode = statusCode
 }
}

const error = new CustomError("message", statusCode)
throw error
Treharne answered 4/5, 2023 at 16:44 Comment(0)
P
3
try{
 // custom error throw in javascript ...   

 const exception = new Error();
 exception.name = "CustomError";

  exception.response = {
    status: 401,
    data: {
      detail: "This is a custom error",
    },
 };

 throw exception;

} catch (err) {
 //console error with status...
  console.log(err.response);
}
Plasm answered 21/10, 2022 at 8:2 Comment(0)
F
1

based on response

const error = new Error(response?.error || 'error message here'); // error message
error.code = response?.code || 404; // you can custom insert your error code
error.name = "NOT FOUND"; // you can custom insert your error name
throw error;
Fool answered 17/4, 2022 at 11:33 Comment(0)
H
1

I had a similar requirement and made my own Error class to provide the required functionality:

interface ApiErrorOptions extends ErrorOptions {
  status?: number;
}

class ApiError extends Error {
  status: number;
  constructor(message: string, options?: ApiErrorOptions) {
    super(message, { cause: options?.cause });
    this.status = options?.status;
  }
}

export async function getApiError(response: Response) {
  const body = await response.json();
  return new ApiError(body.msg || "server_error", {
    status: body?.status,
  });
}
Headforemost answered 10/10, 2022 at 16:37 Comment(0)
S
0

You can create your own exception:

class CustomError extends Error {
  status?: number; // Explicitly declaring the status property

  constructor(message: string, status?: number) {
    super(message);
    this.status = status;
    this.name = this.constructor.name;
  }
}

Usage:

throw new CustomError("Not Found", 404);
throw new CustomError("Internal Error");
Salesperson answered 25/3 at 10:29 Comment(1)
This is not significantly different from the existing answer here.Sayre
B
-3

very simple you can try this

 res.status(403).json(error.message)
Bra answered 11/7, 2023 at 10:7 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Dixil

© 2022 - 2024 — McMap. All rights reserved.