This ArcOS wiki is still under active development, and contains errors and unfinished pages.

Error handling

Oh no! An exception occured. What can you do about it? Well, it depends. ArcOS has error handling measures built-in to prevent it from crashing when you make a mistake. However, there is only so much I can do with the JS engine being the way it is. This page covers some best practices when it comes to error handling.

Callbacks

If you have a callback, like an HTML event or a user preferences update, please make sure to wrap the code inside that callback in a try/catch if it can possibly error. If you don't, ArcOS' global error handling will take over and declare it as a system-wide crash. That's not what you want, is it? Say we have this event listener:

saveButton.addEventListener("click", () => {
    this.saveFile();
})

That saveFile call runs outside the initial scope of the App Renderer's error handling, so an error in this callback will crash ArcOS. This even happens if you wrap the entire addEventListener call:

try {
  saveButton.addEventListener("click", () => {
    this.saveFile();
  });
} catch (e) {
  Debug(`Error: ${e}`);
}

because of the same problem. Instead, you can either wrap the saveFile call inside of the callback, or you can make sure the saveFile method correctly handles errors. Say we have the saveFile method as such:

async saveFile() {
  const path = this.path();
  const contents = this.contents();
  
  const prog = await this.userDaemon.FileProgress(
    {
      type: "size",
      caption: `Saving file...`,
      subtitle: path,
      icon: DriveIcon,
    },
    this.pid
  );

  await this.fs.writeFile(path, textToBlob(contents), async (progress) => {
    await prog.show();
    prog.setMax(progress.max);
    prog.setDone(progress.value);
  });

  await prog.stop();
}

Let's wrap the error-prone parts in a try/catch to prevent them from crashing the OS:

async saveFile() {
  const path = this.path();
  const contents = this.contents();
  
  let prog;
  
  try {
    prog = await this.userDaemon.FileProgress(
      {
        type: "size",
        caption: `Saving file...`,
        subtitle: path,
        icon: DriveIcon,
      },
      this.pid
    );

    await this.fs.writeFile(path, textToBlob(contents), async (progress) => {
      await prog.show();
      prog.setMax(progress.max);
      prog.setDone(progress.value);
    });
  } catch (e) {
    this.saveFailed(e); // Gracefully handle the error
  }

  await prog?.stop();
}

Ofcourse you would ideally display a message box or notification or something to the user to inform them that the operation failed, but hopefully you get the idea.

Last updated