Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass error reason in thrown object / How to handle errors in modern JavaScript [closed]

I am developing a small Node.js package which contains a parser. It throws as soon as it detects a non-recoverable problem.

I have used Java for quite some years and I am used to a mass of exception classes.

But this is JavaScript. I guess it's a matter of style. My essential problem is how to pass the error reason to catch blocks. I thought of creating either different Error "classes" for different error reasons, each taking care of details about each problem, or a single Error class which holds the reason as a property.

Let me give you an example of handling both kinds of errors:

catch(e) {
  if(e instanceof FirstError) {
    ...
  }
  if(e instanceof SecondError) {
    ...
  }
}

catch(err) {
  if(err instanceof AnError) {
    if(err.detail === 'becauseOfA') {
      ...
    }
    if(err.detail === 'becauseOfB') {
      ...
    }
  }
  ...
}

Which of the approaches is better? Both will work, but I don't like the first. Many classes seem to me like an huge overhead.

Edit:
I agree on using callbacks (also answered here):

// One class per error type
function(err, ast) {
  if(err) {
    if(err instanceof FirstError) {
      ...
    }
    if(err instanceof SecondError) {
      ...
    }
  }
  ...
}

// One class for all errors
function(err, ast) {
  if(err) {
    if(err instanceof AnError) {
      if(err.detail === 'becauseOfA') {
        ...
      }
      if(err.detail === 'becauseOfB') {
        ...
      }
    }
    ...
  }
}

// No class at all
function(err, ast) {
  if(err) {
    if(err.detail === 'becauseOfA') {
      ...
    }
    if(err.detail === 'becauseOfB') {
      ...
    }
    ...
  }
}

The problem persists: Should I drop all classes and use a simple object without any prototypal inheritance? I need to pass information about the problem to the error handler (whether catch or callback).

I want to keep this function synchronous because it is tiny and fast (yes, I know that a callback does not make a function async). AFAIK Node.js itself throws Errors in synchronous code (fs.readFileSync) whilst passing error objects to callbacks in asynchronous functions (fs.readFile).

like image 642
just lerning Avatar asked Jun 14 '13 23:06

just lerning


1 Answers

I think, that the best approach for node is to rewrite your module in callback-style. Though you should pass to callbacks two arguments: the first is error or null (if operation completed successfully), the second is the result of operation (or null or undefined, if an error occurred).

Than you can simply handle them in your callback. You may pass errors as strings, then just case(error) to handle different situations.

UPD:

For sync methods you may use throws, but you also may throw just strings and then switch them. If you want typize you errors (for example, if method may throw very different errors (in Java code they may be described in different classes)), you may use object looks like this: { error: 'error_name', type: 'error_type' }.

And then switch(err.type), switch(err.error).

Using classes for this in Javascript is not the best approach, because it simply creates object with prototype property, pointing to constructor object, and instaceof compares that pointers.

like image 82
Yurij Avatar answered Nov 15 '22 19:11

Yurij