On Sat, May 2, 2020 at 12:39 PM Henk-Jaap Wagenaar <wagenaarhenkjaap@gmail.com> wrote:
Of course, there are other ways of writing this code, but imagine this for a database interface where a save normally returns the saved object (inspired by Django)

```
try:
    x, y = Foo.save()
except ValueUnpackingError:
    // oh... this means saving failed (it returned None instead)
    // let's return a sensible response
    return ExceptionToResponse(FooStateToException(foo.state))
```

My concern is that this is risky code. If `Foo.save()` has a bug somewhere inside (or maybe it calls back to your own code which has a bug) it could raise `ValueUnpackingError` for different reasons, and then that gets caught and misleads people into thinking that Foo.save returned None which leads to all sorts of frustration and confusion.

This code:

```
result = Foo.save()
if result is None:
    return ExceptionToResponse(...)
x, y = result
```

is not sexy, but it's explicit, safe, and it targets the real problem precisely.

Creating these new exceptions would encourage people to write code that will bite them later.
 
Another example would be an interactive session where you expect an iterable to have 3 entries (say for a 3D space coordinate) and you want to check this specifically:

```
try:
    x, y, z = point
except ValueUnpackingError:
    print(f"point has wrong dimension")
```

where point is an instance of:

```
class Point:
    def __iter__(self):
        return (float(x) for x in self._internal)
```

The first example made sense, this is too much of a contrived toy example. Why would you write that try/except in an interactive session? How does catching the exception leave you better off than just letting it bubble up and show you a traceback? What are you going to do after now that x,y,z are undefined variables? How did you end up with a point of unknown dimension?

Can you spot here why ValueError would result in significantly different behaviour? ValueError will also catch it if point's internal list contains a bad entry (e.g. a string that does not convert to a float).

The solution here is to ensure that the strings are converted to floats long before iteration, either by Point or by its producer. That's the kind of solution programmers should look for. Catching exceptions in general should be a last resort, and making it slightly less wrong may do more harm than good.