I am not sure if this is right or wrong, but something deep inside me tells me that i am doing it wrong to have logic code on catch stm.
For ex my catch looks something like this:
try{
// do some stuff that throws some unexpected errors
}
catch (error) {
if (error?.graphQLErrors[0]) {
let msg = error.graphQLErrors[0].message
switch (msg) {
case 'limited':
// TODO:: handle
default:
window.location.href = "www.someurl.com";
}
}
Mainly I am thinking that catch stm usually should stay short and clean without logic on it that can cause another error or exception, what happens if the code inside catch throws some error?
It's just fine to have logic in your catch block, if the logic is there in order to handle or report the error. That's what catch blocks are for.
what happens if the code inside catch throws some error?
That's a new error. If you don't catch it, it will propagate to the caller, etc.
Example:
function example() {
try {
// "x" has no method `foo` so this causes an error:
"x".foo();
} catch (e) {
console.log(`Caught error in \`example\`: ${e.message}`);
// "y" has no method `bar` so this causes an error:
"y".bar();
}
}
function wrapper() {
try {
example();
} catch (e) {
console.log(`Caught error in \`wrapper\`: ${e.message}`);
}
}
wrapper();
Throwing errors intentionally from the catch block is a common practice in many places. You can wrap the original into one that can be better handled higher up or perhaps throw a more meaningful error
class MyError extends Error {
constructor(errorCode) {
super();
this.errorCode = errorCode;
}
}
function example() {
try {
// "x" has no method `foo` so this causes an error:
"x".foo();
} catch (e) {
throw new MyError(42);
}
}
function wrapper() {
try {
example();
} catch (e) {
if (e.errorCode === 42) {//specific
console.log(`I know what this error means: the flux capacitor is broken`);
} else {//generic
console.log(`Caught error in \`wrapper\`: ${e.message}`);
}
}
}
wrapper();
can I have logic code if else statements within catch statement?
Yes.
what happens if the code inside catch throws some error?
The error will propagate to the next try catch block.
Related
I have one question that how I can control 2 errors in try / catch throw?
My code is here:
What if 2 errors occur at the same time in try / catch through?
const downloadFiles = async () => {
try {
setKeyState(ValueState.Success);
setValueState(ValueState.Success);
} catch (err) {
if (err instanceof WrongKeyError) {
setKeyState(ValueState.Error);
} else if (err instanceof WrongValueError) {
setValueState(ValueState.Error);
}
}
};
When setKeyState is wrong, the state is ValueState.Error
When setValueState is wrong, the state is ValueState.Error
But when both are wrong, just one of the states is ValueState.Error.
Why and How can I fix it to be able to make both of their states are ValueState.Error?
Thank you.
JavaScript is single-threaded. Multiple errors cannot happen at the same time. Here, if setKeyState throws, the call of setValueState will never be reached - so even if it throws an error, there will never be a WrongValueError. You'll need a separate try/catch.
const downloadFiles = async () => {
try {
setKeyState(ValueState.Success);
} catch (err) {
if (err instanceof WrongKeyError) {
setKeyState(ValueState.Error);
}
}
try {
setValueState(ValueState.Success);
} catch (err) {
if (err instanceof WrongValueError) {
setValueState(ValueState.Error);
}
}
};
That said, it's pretty weird for a function to possibly throw a synchronous error like this. Better for setKeyState and setValueState to be designed so that they don't throw.
I have this "test" code:
function func1(){
try{
...stuff...
}catch(err){
throw new Error();
}
}
function func2(){
try{
func1();
}catch(err){
console.log("ERROR")
}
}
func2();
I have a function that throws an error in the catch in a try-catch-statement. I want it to, if func1 throws Error, it gets caught by the first try-catch-statement, but when I try this, it doesn't get caught by the first statement, it just pauses the code and returns the error. What have I done wrong? and is this the wrong way to do it?
This code should give you an idea of how try/catch blocks work. In the first function call, we call func2 which has a try/catch block. You can see in the console that the error is caught and execution continues. Then we call func1 which throws an uncaught error, which shows up in the console as an error.
function func1() {
console.log('func1...');
throw new Error('something bad happened!');
}
function func2() {
console.log('func2...');
try {
func1();
} catch (err) {
console.log('Caught error');
}
}
console.log('func2()');
func2();
console.log('func1()');
func1();
There is no need for a separate try/catch block in func1 because, it is already within the error handler of func2. In this case, whatever error you throw from func1 will automatically caught by func2
function func1() {
throw new Error('oops');
}
function func2() {
try {
func1();
} catch(err) {
alert(err.message);
}
}
func2();
Not sure exactly where you are stuck but this should work:
Make sure you check your real console
function func1() {
try {
throw new Error('hi from func1')
} catch (err) {
throw err;
}
}
function func2() {
try {
func1();
} catch (err) {
// this doesn't work in stack snippets console
// hit f12 to see your real console
console.log('catched in func2', err)
}
}
func2();
I have error handling set up using try/catch blocks, which in its simplified form looks like this
try {
// .. Some application logic
try {
// .. some async api code
} catch (e) {
throw new Error("Api Error")
}
return true;
} catch (e) {
throw new Error("Unknown Error")
}
And the issue is, whenever I expect "Api Error" to be returned I get "Unknown Error" it seems like all errors are propagated to the outermost catch?
Is there a way to avoid this or another approach that allows for nested error handling?
In your code, check if exception is happening inside the first try block. If so, the inner try won't be executed.
try {
// .. Some application logic
// exception occurs here
// below code is not executed and the control is given to catch block
try {
//this did not execute
// .. some async api code
} catch (e) {
throw new Error("Api Error")
}
return true;
}
catch (e) {
//control came here
throw new Error("Unknown Error")
}
This is also a possible case:
try {
// .. Some application logic
// no exceptions occur here
// below code is executed
try {
//this did not execute
//exception here
// .. some async api code
} catch (e) {
//control came here and this threw APIerror
throw new Error("Api Error")
}
//this did not execute as the previous catch block raised another exception
return true;
}
catch (e) {
//control came here
throw new Error("Unknown Error")
}
Hope this helps :)
So recently I was asked a question :
Is there a way to throw an error without using throw in javaScript ?
As far as I knew about errors, there was only one way to throw an error in JavaScript and that was using throw statement in JavaScript like so :
var myFunc = () => {
// some code here
throw 'Some error' // in a conditional
// some more code
}
try {
myFunc()
}catch(e) {
console.log(e)
}
And not knowing any other way I said No, there is no other way. But now I'm wondering whether I was right ?
So the question is whether or not you can throw a custom error in JavaScript without using throw
Restrictions :
Kindly no using eval , Function.
Don't use throw in your code
Additional :
If you can throw an error without using the word Error
Generators do have a throw method that is usually used to throw an exception into the generator function code (at the place of a yield expression, similar to next), but if not caught it bubbles out of the call:
(function*(){})().throw(new Error("example"))
Of course, this is a hack and not good style, I have no idea what answer they expected. Especially the "no division by zero" requirement is sketchy, since division by zero does not throw exceptions in JS anyway.
If all you want to do is throw an error then just do an invalid operation. I've listed a few below. Run them on your browser console to see the errors (tested on chrome and firefox).
var myFunc = () => {
encodeURI('\uD800'); // URIError
a = l; // ReferenceError
null.f() // TypeError
}
try {
myFunc()
}catch(e) {
console.log(e);
}
function throwErrorWithoutThrow(msg) {
// get sample error
try {
NaN();
} catch (typeError) {
// aquire reference to Error
let E = typeError.__proto__.__proto__.constructor;
// prepare custom Error
let error = E(msg);
// throw custom Error
return Promise.reject(error);
}
}
throwErrorWithoutThrow("hi")
/* catch the error, you have to use .catch as this is a promise
that's the only drawback, you can't use try-catch to catch these errors */
.catch((e) => {
console.log("Caught You!");
console.error(e);
});
I think, if you want to use try...catch blocks, you will need to throw something to get to the catchpart. You can use pretty much everything that fails with an error to do that (like mentioned in the other posts).
If at some point, you want to run-or-die without having to write the throw statement yourself, you can always do an assertion:
const myFunction = () => {
try {
assert.fail();
console.log(`Did not work :)`);
} catch (e) {
console.log(`OK`);
}
};
Of course I would rather try to assert something positive (more Zen), that I need in order to continue.
const myTypeErr = () => `This is a Custom Err Message... \nand it`()
try {
myTypeErr()
} catch(e) {} // caught
myTypeErr() // Uncaught TypeError: "This is a Custom Err Message...
// and it" is not a function
If I have following
function ValidationException(nr, msg){
this.message = msg;
this.name = "my exception";
this.number = nr;
}
function myFunction(dayOfWeek){
if(dayOfWeek > 7){
throw new ValidationException(dayOfWeek, "7days only!");
}
}
Question is:
How can I catch this particular exception in catch block?
JavaScript does not have a standardized way of catching different types of exceptions; however, you can do a general catch and then check the type in the catch. For example:
try {
myFunction();
} catch (e) {
if (e instanceof ValidationException) {
// statements to handle ValidationException exceptions
} else {
// statements to handle any unspecified exceptions
console.log(e); //generic error handling goes here
}
}