0

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
    You are blocking the main thread so it can't print anything to the console – Konrad Mar 16 '23 at 17:39
  • have you used other programming languages before javascript? – Mulan Mar 16 '23 at 17:41
  • That would depend on your console. Some implmentations are not rendering anything until the script finishes (which can take quite some time with synchronous blocking `prompt()`s). But if I run it from the Chrome devtools console, it prints immediately. – Bergi Mar 16 '23 at 17:56
  • Mulan: "have you used other programming languages before javascript?" Yes Mulan... I come from C and C++ world to JavaScript. This is propably why some of these JavaScript features puzzle me. :) – Jarkko Hietala Mar 17 '23 at 15:28
  • Bergi: "That would depend on your console. Some implmentations are not rendering anything until the script finishes" Thank you for clarification. Yes I kind of suspected something like this but was not fully sure. It seems like under the hood these errors are happening but my enviroment is not rendering them to console logs until loop finishes. – Jarkko Hietala Mar 17 '23 at 15:30

1 Answers1

0

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)
      }
    })
  })
}
Konrad
  • 21,590
  • 4
  • 28
  • 64
  • Thank you. This solution works and helps testing javascript code when it's run in an environment that can't otherwise render the console while the code is executing. I would vote this solution, but I still miss 4 karma points to unlock the voting ability. – Jarkko Hietala Mar 17 '23 at 17:33