最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

error handling - JavaScript anti-silent techniques to indicate failure - Stack Overflow

programmeradmin0浏览0评论

What would be a good way to report errors in JavaScript instead of relying on nulls, and undefineds when errors do occur and a function is unable to proceed forward. I can think of three approaches:

  1. do nothing
  2. throw an exception
  3. assert

Here's a simple example scenario - a function that credits a user account with the amount passed in. The function credit is part of an Account object.

Here's the naive solution.

function credit(amount) {
   this.balance += amount;
}

A major problem with this approach is invalid data. Let's fix it up, and use a return value to indicate that the operation failed.

function credit(amount) {
    if(!isInt(amount)) {
        return false;
    }
    this.balance += amount;
}

This is an improvement over the previous one, but client code will have to check the return value to ensure that the operation succeeded. Doing this for basically every method in the system can bee cumbersome.

if(!johnDoe.credit(100)) {
    // do some error handling here
}

A third approach, similar to the second one, is to throw an exception. Since we are throwing the exception ourselves, could throw a specific type of exception rather than a general one.

function credit(amount) {
    if(!isInt(amount)) {
        throw new InvalidAmountError(amount);
    }
    this.balance += amount;
}

A fourth approach similar to throwing exceptions is to use assertions in your code. One shorting pared to the above approach is that since the assert is generic, we lose the ability to throw custom exceptions. It is still possible though by passing the object to throw in each assert call.

function credit(amount) {
    assert(!isInt(amount), "Amount to credit is not an integer");
    this.balance += amount;
}

A global assert function is easy to write and makes the code a little shorter.

function assert(value, message) {
    if(value !== true) {
        throw new AssertionError(message);
    }
}

function AssertionError(message) {
    this.message = message;
}

AssertionError.prototype.toString = function() {
    return 'AssertionError: ' + this.message;
}

Out of these approaches, what would be a good way to deal with unexpected values, and unhappy paths. Are there any other approaches not mentioned here that could be useful?

What would be a good way to report errors in JavaScript instead of relying on nulls, and undefineds when errors do occur and a function is unable to proceed forward. I can think of three approaches:

  1. do nothing
  2. throw an exception
  3. assert

Here's a simple example scenario - a function that credits a user account with the amount passed in. The function credit is part of an Account object.

Here's the naive solution.

function credit(amount) {
   this.balance += amount;
}

A major problem with this approach is invalid data. Let's fix it up, and use a return value to indicate that the operation failed.

function credit(amount) {
    if(!isInt(amount)) {
        return false;
    }
    this.balance += amount;
}

This is an improvement over the previous one, but client code will have to check the return value to ensure that the operation succeeded. Doing this for basically every method in the system can bee cumbersome.

if(!johnDoe.credit(100)) {
    // do some error handling here
}

A third approach, similar to the second one, is to throw an exception. Since we are throwing the exception ourselves, could throw a specific type of exception rather than a general one.

function credit(amount) {
    if(!isInt(amount)) {
        throw new InvalidAmountError(amount);
    }
    this.balance += amount;
}

A fourth approach similar to throwing exceptions is to use assertions in your code. One shorting pared to the above approach is that since the assert is generic, we lose the ability to throw custom exceptions. It is still possible though by passing the object to throw in each assert call.

function credit(amount) {
    assert(!isInt(amount), "Amount to credit is not an integer");
    this.balance += amount;
}

A global assert function is easy to write and makes the code a little shorter.

function assert(value, message) {
    if(value !== true) {
        throw new AssertionError(message);
    }
}

function AssertionError(message) {
    this.message = message;
}

AssertionError.prototype.toString = function() {
    return 'AssertionError: ' + this.message;
}

Out of these approaches, what would be a good way to deal with unexpected values, and unhappy paths. Are there any other approaches not mentioned here that could be useful?

Share Improve this question edited Jul 17, 2010 at 1:28 Anurag asked Jul 17, 2010 at 1:16 AnuragAnurag 142k37 gold badges222 silver badges261 bronze badges 4
  • This is one of the most annoying aspects of dynamically typed languages. – ChaosPandion Commented Jul 17, 2010 at 1:25
  • @meder - haha, alert is the loudest of them all :) – Anurag Commented Jul 17, 2010 at 1:30
  • @ChaosPandion - it is a huge problem in dynamically typed languages because the additional type checks may need to be done. Although even statically typed languages can be problematic because of null and some other factors. For example, each method must check if a given object is null or not. – Anurag Commented Jul 17, 2010 at 1:35
  • As a parison point, Microsoft does type/argument checking in the "debug" version of their client Ajax scripts, while the "release" version excludes many of the same checks, to reduce function call overhead, and, presumably, because you've resolved your "invalid argument" calls during the development phase ;) See "Script Support" at msdn.microsoft./en-us/library/bb398874(loband).aspx – Crescent Fresh Commented Jul 17, 2010 at 13:14
Add a ment  | 

2 Answers 2

Reset to default 3

Consider a client-side logging framework to report errors, such as Log4js. One can log messages (i.e., info, debug, warn, error) in the browser or persist messages to the server via Ajax, depending on the application.

The Log4js site also provides a list of other JavaScript logging frameworks.

A good approach, using your custom exception example, would be to throw the exception and log the error as you see fit.

One shorting pared to the above approach is that since the assert is generic, we lose the ability to throw custom exceptions

Not necessarily:

function assert(value,message,Exctype) {
    if(value !== true) throw new Exctype(message);
}

Constructors are functions. Functions are first class values. Feel free to pass 'em around.

发布评论

评论列表(0)

  1. 暂无评论