Hacker News new | past | comments | ask | show | jobs | submit login

You clean up processing that your own method is responsible for. For example, rolling back transactions that it has started, deleting temporary files that it has created, closing handles that it has opened, and so on and so forth. You rarely if ever need to know what kind of exception was thrown or why in order to do that.

You can only assume that the methods you have called have left their own work in a consistent state despite having thrown an exception. If they haven't, then they themselves have bugs and the appropriate cleanup code needs to be added there. Or, if it's a third party library, you should file a bug report or pull request with their maintainers.

You don't try to clean up other people's work for them. That would just cause confusion and result in messy, tightly coupled code that is hard to understand and reason about.




Do you write a try block around every call you make? How do you know what calls will throw exceptions and unwind the stack?


Usually, no you don't. You only write a try ... catch or try ... finally block round the entire method body, from the point where you create the resources you may need to clean up to the point where you no longer need them. For example:

    var myFile = File.Open(filename);
    try {
        while ((var s = file.ReadLine()) != null) {
            var entity = ProcessLine(s);
            // do whatever you need to do to entity
        }
    }
    finally {
        myFile.Dispose();
    }
C# gives you the using keyword as syntactic sugar for this:

    using (var myFile = File.Open(filename)) {
        while ((var s = file.ReadLine()) != null) {
            ProcessLine(s);
            // do whatever you need to do to entity
        }
    }


That sounds incredibly ugly and painful.


It isn't in practice. Only a minority of methods actually need it.

It's certainly far, far better than having to add exactly the same check after every method call. Which is only what you need to do if you're working in a situation where exceptions are not an option.


“railway oriented programming” (aka nomadic effects) don’t require that.

As a bonus, you can’t accidentally fail to catch an exception, and you can model much more complex error handling than just ”catch and raise.”

For example, it’s trivial to implement error recovery, where you implicitly collect all errors that occurred and then can report them once at the end.


I'll add that C# also has using statements that dispose the object when the current scope exits (including if it exits due to an exception) this significantly cuts down on ugliness .




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: