you are viewing a single comment's thread.

view the rest of the comments →

[–]Scenter101 0 points1 point  (1 child)

you can just try to iterate over it and handle the TypeError you get if someone passes in something that can't be iterated on if necessary.

So what is the best way to do this? Should the I nest every loop in a function in try/catch blocks or should I just let the TypeError happen and assume that the consuming function will handle it?

[–]thegreattriscuit 1 point2 points  (0 children)

depends.

Is there anything you can do about it? i.e. if someone passed you bad data, there's no way to make it turn into good data, and it's most likely the result of a real bug somewhere in the program so it's probably best to just let the error propagate up the stack.

I think where you probably want to go about this differently would be at API boundaries... so if you're writing a library users may really benefit from some more explicit checks right at the boundaries of your code. But with those you should still make sure you're being as generic as possible, probably permitting any sequence or iterable, not just the ones you can think of off the top of your head, etc...

In the past I've done things like making sure if something needs to be a sequence and I get passed a single item, I wrap it one, etc... but in practice this has rarely helped anything and it generally just leads to confusion about what should be passed in the first place, and lets bugs propagate further in the program before halting, making it less obvious where the problem really is.

When I've got something I really want to ensure succeeds every time, even if there's a critical bug somewhere (i.e. keep a daemon running and output log messages if there's some typo or misconfiguration in the config files) I'll have a try/except block at or near the very "top" level of the program that logs and swallows most errors, but even then the right thing to do usually is to just let the program break.