This may be an elementary question, but it is breaking my brain.
I have a structure like this in NodeJS (typescript):
while(true) {
if (something) {
code...
try{
dangerousCode();
}catch(e){
console.log(e);
//Now I want to exit from this if statement and go to the next one
}
some other code...
}
if (somethingElse) ...
}
How can I leave a catch statement like that and go to the next if (so I need to currently leave the if statement where the catch block is). Should I use break or continue keyword? Should I do something else?
try something like this
while(true) {
if (something) {
code...
try{
dangerousCode();
some other code...
}catch(e){
console.log(e);
// Now you will exit this if block, as there are no more instructions
}
}
if (somethingElse) ...
}
If an exception is thrown, it will get caught and handled in the catch block and then directly go the next if statement.
If no exception occurs, the dangerousCode() will execute normally and pass to some other code... after it.
You will have to add another variable and a condition in this case.
let enterFirstIfBlock = true;
while(true) {
if (enterFirstIfBlock && something) {
code...
try{
dangerousCode();
} catch(e) {
console.log(e);
enterFirstIfBlock = false;
}
if (enterFirstIfBlock) {
some other code...
}
}
if (somethingElse) ...
}
while(true) {
if (something) {
code...
try{
dangerousCode();
}catch(e){
console.log(e);
//Now I want to exit from this if statement and go to the next one
}
some other code...
}
if (somethingElse) ...
}
I suggest you move your second if statement to a function say doSomething(), and then call this function within your catch block, and after first if, like this:
while(true) {
if (something) {
code...
try{
dangerousCode();
}catch(e){
console.log(e);
doSomething();
continue;
//Now I want to exit from this if statement and go to the next one
}
some other code...
}
doSomething();
}
function doSomething() {
if (somethingElse) ...
}
You will need to pass appropriate params, and handle them accordingly, and also add continue in after doSomething in catch if nothing else is required.
An esoteric, but occasionally convenient feature is using a label with a block scope.
label
The labeled statement can be used with break or continue statements. It is prefixing a statement with an identifier which you can refer to.
It allows you to break out of a code block by its label name and continue execution after the end of the block. Here's a contrived example to demonstrate how to use it. (Of course, see the linked documentation as well.)
function fork () {
return Math.random() < 0.5;
}
function getValue () {
const useFirst = fork();
if (fork()) return useFirst ? 'a' : 'b';
return useFirst ? 1 : 2;
}
while (true) {
let value = getValue();
stringCheck:
if (typeof value === 'string') {
// code...
try{
if (fork()) throw new Error('Bad luck');
}
catch (ex) {
console.error(ex);
break stringCheck; // Breaks out of the block associated with the label
}
// some other code...
}
value = getValue();
numberCheck:
if (typeof value === 'number') {
console.log('Got a number');
// break numberCheck; // If uncommented, would break out of this block
break; // Break out of the while loop
}
}
Related
This question already has answers here:
Uses of the finally statement
(9 answers)
Closed 1 year ago.
This question may appear similar to others that have been answered, but I can't find an answer relating to JavaScript.
What is the difference between code in a finally block and code that comes after the entire try ... catch ... finally statement?
That is, what is the difference between this code:
try {
f(x);
}
catch(e) {
g(e);
}
finally {
h(y);
}
and this code:
try {
f(x);
}
catch(e) {
g(e);
}
h(y);
One difference is that, if a value is returned in a finally, it will override values returned from inside the prior try and catch blocks:
function foo() {
try {
throw new Error('1');
} catch(e) {
return '2';
} finally {
return '3';
}
}
console.log(foo());
Returning from a finally will also prevent throws in a try or catch from percolating outward - instead, only the finally's normal return completion value will be the result.
(function() {
try {
try {
throw new Error('oops');
} catch (ex) {
console.error('inner', ex.message);
throw ex;
} finally {
console.log('finally');
return;
}
} catch (ex) {
// not entered into
console.error('outer', ex.message);
}
})();
I'll admit this question had me scratching my head at first. But a look at the MDN reference for try...catch includes this salient section on "Returning from a finally-block". It appears that if you return from a finally block, it will override anything returned or thrown from the preceding try or catch blocks. So while your example may be identical, if you were to change it to this:
try {
return f(x);
}
catch(e) {
throw g(e);
}
finally {
return h(y);
}
...it would fundamentally differ from this:
try {
return f(x);
}
catch(e) {
throw g(e);
}
return h(y);
How can I break the parent function depending from a child function's outcome as a way of checking everything in case something is not ok in a child function? I currently have the following:
function Parent() {
Step1();
Step2();
Step3();
}
and I would like to break the parent function if child function "Step1()" is not completed, for example.
I thought I could create a global variable as a flag, combined with an if statement within the parent function such that if the flag would change from "true" to "false" within the child function, the whole parent function would break, but this didn't work giving an error saying the "break is illegal". This is what I tried:
var flag = "true" // Global variable
function Parent() {
Step1(); //Within this child function, I have an "if" condition that sets flag "true"/"false" depending on the outcome
if (flag == "false") { //I was hoping this would read the incoming flag and trigger a break, if the flag was set to "false" in Step1();
}
Step2();
Step3();
}
Right now my script goes through all child functions even if Step1() is incorrect, and without a way to stop this sequence, I'll just keep getting undesirable results from the parent function.
I also thought that if I used "break;" at any point in the whole .gs file it would break the whole thing but it's not the case. If I run Step1() on its own and the "if" conditions activate the "break;" it breaks succesfully, but when I run the parent function it just keeps going onto the next function.
Thanks,
Nestor
To successfully break, add a return
The return statement ends function execution
if (flag == "false") { return; }
Alternatively, you could throw a error or play with try...catch
Live snippet:
let flag = 0;
function main() {
console.info("main1");
function step1() {
console.info('step1');
flag = 1;
}
function step2() {
console.info('step2');
}
step1();
if (flag) return; //stops execution
step2();
}
function main2() {
console.info("main2");
function step1() {
console.info('step1');
}
function step2() {
console.info('step2');
throw new Error('Step 2 fatal error');
}
function step3() {
console.info('step3');
}
try {
step1();
step2();
step3();
} catch (e) {
console.error(e.message);
}
}
main();
main2();
apply blow logic
let flag = true;
function(){
if (flag == "false") {
"false" in child1();
goto lineContinue
}
child2();
child3();
}
lineContinue: child4();
I'm trying to create a function that's responsible for checking a boolean and exiting early with a warning, if true.
Here's example of what i'm trying to achieve:
function warnAndDie(shouldDie) {
if(shouldDie) {
console.log("go away, i'm dying!");
// TODO: some code to cause the calling function to exit early
}
}
function triggerTheWarnAndDie() {
shouldWarnAndDie(true);
console.log("I should never run!");
}
function dontTriggerTheWarnAndDie() {
shouldWarnAndDie(false);
console.log("I should run!");
}
What can i do so that warnAndDie is able to cause the calling functions to terminate early?
thank you
You have several options. I'll list the two very basic ones for you:
Return a value (probably boolean) and return early from you caller depending on the initial return value
function shouldWarnAndDie(shouldDie) {
if(shouldDie) {
console.log("go away, i'm dying!");
return true;
}
return false;
}
function triggerTheWarnAndDie() {
var hasDied = shouldWarnAndDie(true);
if (hasDied) return;
console.log("I should never run!");
}
Throw an exception
function shouldWarnAndDie(shouldDie) {
if(shouldDie) {
throw "Go away, i'm dying!";
// or cleaner:
// throw new dyingException("Go away, i'm dying!");
}
}
function triggerTheWarnAndDie() {
try {
shouldWarnAndDie(true);
console.log("I should never run!");
}
catch(err) {
console.log(err+" He's dead Jim!");
}
}
There are more advance mechanics which are probably out of scope for you right now, but LINQ's nice answer about callbacks and promises is definitely worth a look.
This can be achieved with basic exception handling. Here I have created a custom exception which can be caught using a try catch statement.
function shouldWarnAndDie(shouldDie) {
if(shouldDie) {
throw new DyingException();
}
}
function triggerTheWarnAndDie() {
try {
shouldWarnAndDie(true);
} catch(err) {
console.log(err.message);
return;
}
console.log("I should never run!");
}
function dontTriggerTheWarnAndDie() {
try {
shouldWarnAndDie(false);
} catch(err) {
console.log(err.message);
return;
}
console.log("I should run!");
}
// custom Exception handler
function DyingException() {
// do some custom exception handling here
return new Error("Go away, I am dying!");
}
triggerTheWarnAndDie(); // Go away, I am dying!
dontTriggerTheWarnAndDie(); // I should run!
Here is a JsFiddle Example
use the
return;
keyword to exit
*This is just a quick workaround. You may want to look into error checking and exceptions...
I'd suggest using promises but its not supported natively in all browsers. We can use callbacks where the code inside the callback only gets executed when warnAndDie allows it to execute.
function warnAndDie(shouldDie, fn) {
if(shouldDie) {
console.log("go away, i'm dying!");
// TODO: some code to cause the calling function to exit early
return;
}
fn();
}
function triggerTheWarnAndDie() {
shouldWarnAndDie(true, function () {
console.log("I should never run!");
} );
}
function dontTriggerTheWarnAndDie() {
shouldWarnAndDie(false, function () {
console.log("I should run!");
} );
}
I have tried this code in javascript
function abc(){
try{
console.log(0);
throw "is empty";}
catch(err){
console.log(1);
return true;
}
finally{return false;}
return(4);
}
console.log(abc());
I got output as false. I understand Finally always execute regardless of result of try catch but what happen to return statement in catch .
I understand Finally always execute regardless of result of try catch
but what happen to return statement in catch .
Return statement in catch will be executed only if the catch block is reached, i.e. if there is an error thrown.
For example
function example() {
try {
throw new Error()
return 1;
}
catch(e) {
return 2;
}
finally {
}
}
example() will return 2 since an error was thrown before return 1.
But if there is a finally block and this finally block has a return statement then this return will override catch return statement.
For example
function example() {
try {
throw new Error()
return 1;
}
catch(e) {
return 2;
}
finally {
return 3;
}
}
Now example() will return 3.
In your example, there is a return statement after the finally block. That statement will never get executed.
Try
function example() {
try {
throw new Error()
return 1;
}
catch(e) {
return 2;
}
finally {
return 3;
}
console.log(5)
return 4;
}
It only outputs 3. 5 is never printed since after finally block value is returned.
Finally its always executed the last. So it overrides any other return you have. Therefore, your method returns false
I have a suspicion that I'm using the finally block incorrectly, and that I don't understand the fundamentals of its purpose...
function myFunc() {
try {
if (true) {
throw "An error";
}
} catch (e) {
alert (e);
return false;
} finally {
return true;
}
}
This function will run the catch block, alert "An error", but then return true. Why doesn't it return false?
The finally block contains statements to execute after the try and catch blocks execute but before the statements following the try...catch statement. The finally block executes whether or not an exception is thrown. If an exception is thrown, the statements in the finally block execute even if no catch block handles the exception. more
The finally block will always run, try returning true after your try block
function myFunc() {
try {
if (true) {
throw "An error";
}
return true;
} catch (e) {
alert (e);
return false;
} finally {
//do cleanup, etc here
}
}
Finally blocks execute when you leave the try block. In your code this happens when you return false. That sets the return value to false and attempts to exit the function. But first it has to exit the try block which triggers the finally and overwrites the return value to true.
It is considered by many to be a good programming practice to have a single return statement per function. Consider making a var retval at the beginning of your function and setting it to true or false as appropriate throughout your function and then structuring the code so that it falls correctly through to a single return at the bottom.
function getTheFinallyBlockPoint(someValue) {
var result;
try {
if (someValue === 1) {
throw new Error("Don't you know that '1' is not an option here?");
}
result = someValue
} catch (e) {
console.log(e.toString());
throw e;
} finally {
console.log("I'll write this no matter what!!!");
}
return result;
};
getTheFinallyBlockPoint("I wrote this only because 'someValue' was not 1!!!");
getTheFinallyBlockPoint(1);
Run this on your browser's console and it might give you the answer you're looking for.