33

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.

pppery
  • 3,731
  • 22
  • 33
  • 46
Run
  • 54,938
  • 169
  • 450
  • 748
  • "*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`. – VLAZ Sep 13 '21 at 16:18
  • 1
    Why do you need to throw `Error` specifically and not anything else? – VLAZ Sep 13 '21 at 16:19
  • 4
    Either make a custom error subclass that takes a second argument, or use `throw Object.assign(new Error('New error message'), { statusCode: 404 });` – Bergi Sep 13 '21 at 16:23
  • 2
    "*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 https://caniuse.com/mdn-javascript_builtins_error_error_options_cause_parameter – VLAZ Sep 13 '21 at 16:27
  • "*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? – VLAZ Sep 13 '21 at 16:32
  • 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: ""`. 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. – user229044 Sep 13 '21 at 16:50
  • 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. – user229044 Sep 13 '21 at 16:53

7 Answers7

34

You can use err.code

const error = new Error("message")
error.code = "YOUR_STATUS_CODE"
throw error;
Sandeep chand
  • 487
  • 6
  • 7
  • 4
    I have thought of that too. I am trying to reduce these 3 lines to make it shorter. – Run Sep 13 '21 at 16:30
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');
Floxblah
  • 152
  • 9
  • 1
    Why set the prototype if it's not used at all? – VLAZ Sep 13 '21 at 16:21
  • 3
    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`. – Bergi Sep 13 '21 at 16:22
  • 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. – Run Sep 13 '21 at 16:22
4
class CustomError extends Error {
 constructor(message, statusCode) {
  super(message)
  this.statusCode = statusCode
 }
}

const error = new CustomError("message", statusCode)
throw error
samuelraj-dev
  • 41
  • 1
  • 1
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);
}
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;
Ismail Hosen
  • 166
  • 2
  • 4
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,
  });
}
InSync
  • 4,851
  • 4
  • 8
  • 30
jackhkm
  • 71
  • 1
  • 5
-2

very simple you can try this

 res.status(403).json(error.message)
  • 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](/help/how-to-answer). – Community Jul 12 '23 at 18:59