Live data from Hacker News

Error Handling in Node.js

joyent.com

71–80 of 96 posts

Re: Error Handling in Node.js

#71
If you're going to check every argument's type and throw on failure, either use a statically typed language or adopt a concise way of type checking. Many of the examples have big groups of assert() calls at the top. Gross.

Re: Error Handling in Node.js

#72
post #49
post #33

Earlier quoted context omitted.

Once I got used to it I found I kind of like the Go paradigm of checking for errors every time something could go wrong, and (usually) passing the first one up the chain with some additional context info. However, the fact that "ignore error" is an easy and built-in paradigm that even shows up in the official docs: fragileThing, _ := scary.MightNotWork() that fills me with dread.

I think that's in the docs mostly for conciseness. I don't think anyone thinks that it's a good practice in real code.

So you admit Go error as value is verbose. Because they are. The best system ihmo is Java's. If a method throws then IT should be part of the method signature and dealing with the error (try/catch) should be mandatory. The irony is that Go has some form of (inferior) try/catch with panic/recover. So it has both but still pretends exceptions are bad.

Re: Error Handling in Node.js

#73
post #46
post #22

Earlier quoted context omitted.

> Only log actionable items Easy to say but much harder to implement. For example, if you communicate with another service, a few network errors are usually not actionable and you'd have some fallback mechanism in you code. But tons of network errors (e.g. > 20%) is a problem that needs to be fixed now. So would you log the network error or not?

Set a threshold, and log only once you hit that threshold.

And keep track of that state across 20 different instances?

What we do is just log the failure and have a system like New Relic monitoring everything so that it can alert us when we hit 20% network failure.

Re: Error Handling in Node.js

#74
post #48
post #33

Earlier quoted context omitted.

Once I got used to it I found I kind of like the Go paradigm of checking for errors every time something could go wrong, and (usually) passing the first one up the chain with some additional context info. However, the fact that "ignore error" is an easy and built-in paradigm that even shows up in the official docs: fragileThing, _ := scary.MightNotWork() that fills me with dread.

Could you elaborate? Assuming that scary.MightNotWork() is some kind of ancillary function that is non-essential, why would I want to let it impact the main program. The example that comes to mind would be logging. If I have set up my own "Write logs into network share" call, I'd never ever expect it to throw errors that took down the app. Share down? Don't care. logfile locked/corrupt. Don't care. Try and log, if yo…

Sure. If your function does things internally that might return errors, the normal thing to do is have your function also potentially return an error, namely the first error it finds.

If you call a function the error of which isn't a big deal to your function, you'd normally check the return value to make sure it meets your expectations. If it does, fine -- proceed accordingly. If it doesn't, then send the error up the chain.

So -- totally bogus example -- say you want to return the mod time of a file or, if the file doesn't exist, the epoch. The file not existing is an error, but not one you'd abort on; other file errors though would be problematic:

    // ModOrEpoch returns the modification time of the file at path, or the epoch
    // time if there is no such file.  Unexpected file conditions are returned
    // as errors.
    func ModOrEpoch(path string) (time.Time, error) {

    	epoch := time.Unix(0, 0)
    	info, err := os.Stat(path)
    	if err != nil {
    		if os.IsNotExist(err) {
    			return epoch, nil
    		}
    		return time.Now(),
    			fmt.Errorf("File error for %s: %s", path, err.Error())
    	}
    	if info.IsDir() {
    		return time.Now(),
    			fmt.Errorf("File is a directory: %s", path)
    	}

    	return info.ModTime(), nil

    }
https://play.golang.org/p/AMSJMV3tks

I suppose it's possible you might really, really not care about an error, but that would be extremely un-idiomatic in Go. And, I would argue, a very bad habit in any language where the error could possibly be other than what you expect; sort of like

    try { foobar(); } catch(e) { /* global thermonuclear war? */ }
The thing that bugs me about seeing the errors ignored in official docs is that the Go world puts a lot of emphasis on writing idiomatic code, and the Go "idiom" is much less flexible than, say, Perl's. You might reasonably look to the official documentation to learn what is and isn't idiomatic. And you would hopefully figure out soon enough that ignoring errors isn't, but then again you might not.

Re: Error Handling in Node.js

#75

Earlier quoted context omitted.

Error.prototype.toString() reads e.name, not e.prototype.constructor.name, so you can't rely on everyone to have subclassed Error. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

I'm not following, why can't I use: e instanceof Error or: e instanceof MyError why does toString() have anything to do with this?

This is what I do when working with my own Error types.

Re: Error Handling in Node.js

#76
post #46

Earlier quoted context omitted.

Set a threshold, and log only once you hit that threshold.

And keep track of that state across 20 different instances? What we do is just log the failure and have a system like New Relic monitoring everything so that it can alert us when we hit 20% network failure.

Sure - but then the developer-facing "log" is the New Relic interface, and your instances transmit failure information to it via some API (I mean I suppose you could have one program output a plain-text log file and then another program or service parse that to figure out how many errors were happening, but you wouldn't do that for any other kind of inter-system communication).

Re: Error Handling in Node.js

#77
post #72
post #49

Earlier quoted context omitted.

I think that's in the docs mostly for conciseness. I don't think anyone thinks that it's a good practice in real code.

So you admit Go error as value is verbose. Because they are. The best system ihmo is Java's. If a method throws then IT should be part of the method signature and dealing with the error (try/catch) should be mandatory. The irony is that Go has some form of (inferior) try/catch with panic/recover. So it has both but still pretends exceptions are bad.

The problem with checked exceptions is nothing more and nothing less than they didn't work. Yes, in theory, or at least some theories, checked exceptions ought to be awesome. But they aren't in practice. Go's error handling in practice works better than Java checked exceptions. Where fact and theory conflict, fact wins.

(I emphasize "checked" because there is a much more robust and interesting discussion about exceptions in general, and then of course a number of sidecar discussions about other error handling mechanisms like Either/Option, etc. I'm only making this claim about checked exceptions. Which is kinda shooting fish in a barrel; arguably C's error handling worked better than Java's checked exceptions and I think C's "error handling" isn't even worthy of the term.)

Re: Error Handling in Node.js

#78
It beats me why Node.js is anywhere near as popular as Elixir if real concurrency and error handling are a priority. Is programming just a fashion industry? What's popular certainly doesn't seem to have any connection with engineering principles.

Re: Error Handling in Node.js

#79
post #2

Giant post about the nightmare that is making robust code in node.js. Summary, don't use a language in large projects that makes it so easy to leak errors and exceptions. There's something to be said about the compiler forcing you to declare what exceptions your code can throw to force you to think about this stuff up front.

Node is actually best used with Promises, which aren't even mentioned in this post.

Promises, aside from being far more concise with a huge amount of utility, do not leak errors or exceptions.

    doAMillionThings()
    .catch((err) => handleAnything(err));

Re: Error Handling in Node.js

#80
post #78

It beats me why Node.js is anywhere near as popular as Elixir if real concurrency and error handling are a priority. Is programming just a fashion industry? What's popular certainly doesn't seem to have any connection with engineering principles.

I blame non-technical managers who push "microservices" and "node js" because they went to some conference and heard that it's "the best".
Post reply on HN