4

What is the cleanest way to both throw an error and return a value from a Javascript function?

Here's one proposed approach as a starting point:

(e, v) => {
   setTimeout(() => { throw(e) }, 0);
   return v; 
}

Here's a runnable snippet to demonstrate further:

var val = ((e, v) => {
   setTimeout(() => { throw(e) }, 0); // will throw in console
   return v; 
})('errMSG', 1)


alert(val); // 1 

7
  • I'd probably create a custom response class with an error code and response wrapped up. Commented Feb 12, 2018 at 19:05
  • 2
    The proposed approach is broken as the exception is thrown from within an async callback. The original function just returns v, it doesn't throw any exceptions. Commented Feb 12, 2018 at 19:08
  • 3
    Why do you want to do this? Commented Feb 12, 2018 at 19:49
  • @PatrickRoberts I am using RxJS epics in my Redux application, when an epic fails I want to both throw the error and return the source observable so that the epic can restart rather than just dying. Commented Feb 12, 2018 at 20:34
  • 1
    Please provide a concrete example of what you are trying to accomplish. What you are asking doesn't make sense right now. Commented Feb 12, 2018 at 20:52

3 Answers 3

2

Return an object that contains the value you are interested in, and an error:

return {
    value: "foo",
    error: new Error("bar")
}

The receiver can then throw the error as necessary

Sign up to request clarification or add additional context in comments.

2 Comments

Nice, this just delegates the difficulty of getting that error thrown elsewhere though right? How does the caller throw that error with out terminating the call chain? I like the lateral thought though... +1
I've thought of an interesting use case for this. Take lodash's _.get method, to which you provide an object and a path, and it returns the value at that path, if it exists, or undefined if it doesn't exist. We have used this to great effect in a reactive Vue.js application where the value may not exist on first call for instance if it relies on an http call, but the "computed"s will automatically update once the value exists. Nevertheless it might be nice to receive not only the value but also the error if for instance _.get(obj, 'foo.bar.baz') fails, so it can be inspected
0

You can't do both. Throwing an error will either transfer control to a catch statement (at which point it's not thrown anymore), or lacking a catch, will terminate execution of the program.

More here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw

5 Comments

Try it out, the function in the timeout sits on the stack and still throws the error on the next tick after the value has been returned.
But that's a different function. There's no point to creating a function whose only purpose is to throw an exception.
But there is a point, the point is that I want it's parent to return a value and the error to be thrown. That's the whole point of the whole question. How to do that nicely ;)
Just to extend Bill's line of questioning, why do you want to throw an error and return a value? I don't think that's a pattern I have encountered anywhere since generally you throw exceptions because you are operating outside of a defined scope, or the Exception is a value "return" value.
@KaiserDandangi As mentioned in the comments above - I am using RxJS epics in my Redux application, when an epic fails I want to both throw the error and return the source observable so that the epic can restart rather than just dying.
0

When an Error is thrown, the code below the thrown line doesn't execute.

Hence, its impossible to return a value immediately after throwing an error. However, you can send a value along with the error and catch it later.

So,I am Assuming that you want to throw a value with an error...Here's how to do that...

Hope this is somewhat helpful

function UserException(message) {
    this.message = message;
    this.name = 'UserException';
  }
  
  // Make the exception convert to a pretty string when used as a string 
  // (e.g., by the error console)
  UserException.prototype.toString = function() {
    return `${this.name}: "${this.message}"`;
  }

let v = 1010 //
let val = ((e, v) => {
        setTimeout(() => {
      console.log("value from error"+" :"+e.message,",variable v"+" :"+v);
      throw(e);
    }, 0); // will throw in console
})(new UserException(v), v) //

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.