JavaScript Try Catch report errors in console only after program exits

382 views Asked by At

This piece of code is supposed to loop forever until the user enters the correct answer in a prompt. The right answers are "left" and "right". If the user enters any other text, then function promptDirection throw an error and execute catch block then for loop run code again from the start.

What I fail to understand in this code is that why errors like "Not a valid direction. Try again." are not reported to console log every time catch block is executed. Errors come visible only after user enters correct answer or press cancel in a prompt and then it returns "null" and that terminate the program.

Could somebody explain this behaviour?

So I would expect this code throw error in console every time user, type anything else into prompt than left or right. In reality if the user types three times wrong answers then error only come visible after program exit it reports three times "Not a valid direction. Try again." and You chose L or You chose R.

So if I type into prompt: Wrong Wrong Wrong Left

Nothing is visible in console about catch block being triggered three times by InputErrors "Not a valid direction" until the correct answer is typed. All generated errors come visible at browser console all at once after program terminates with correct Left answer is entered.

class InputError extends Error { }
function promptDirection(question) {
  let result = prompt(question);
  if (result.toLowerCase() == "left") return "L";
  if (result.toLowerCase() == "right") return "R";
  throw new InputError("Invalid direction: " + result);
}

for (;;) {
  try {
    let dir = promptDirection("Where?");
    console.log("You chose ", dir);
    break;
  } catch (e) {
    if (e instanceof InputError) {
      console.log("Not a valid direction. Try again.");
    } else {
      throw e;
    }
  }
}

1

There are 1 answers

1
Konrad On

You can fix it by using setTimeout

class InputError extends Error {}

// your function without changes
function promptDirection(question) {
  let result = prompt(question);
  if (result.toLowerCase() == "left") return "L";
  if (result.toLowerCase() == "right") return "R";
  throw new InputError("Invalid direction: " + result);
}

// async function wrapper so you can use await
(async() => {
  for (;;) {
    try {
      let dir = await wait(() => promptDirection("Where?"));
      console.log("You chose ", dir);
      break;
    } catch (e) {
      if (e instanceof InputError) {
        console.log("Not a valid direction. Try again.");
      } else {
        throw e;
      }
    }
  }
})()

// calls a function with `setTimeout`
async function wait(fn) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      try {
        resolve(fn())
      } catch (e) {
        reject(e)
      }
    })
  })
}