Sunday, June 21, 2009

Usage Errors and ArgumentException

I'm a bit defensive when I write software. I'm careful with the preconditions in every method and I always validate arguments of all methods. So I throw ArgumentExceptions a lot. The question is: should the code, which is calling into my code, catch and handle those exceptions or should it let the CLR kill the executing process by letting the exception propagate to the top of call stack unhandled? Many people say it's a good idea not to catch ArgumentExceptions, because those exceptions usually indicate usage errors, therefore, erroneous code must be recompiled, retested and reshipped. I am not sure about this idea being good. Why should everything crash if a method is has been called with improper arguments? The logic that acts as the argument guard must precede any business logic in a method, so if you get an ArgumentException it also says that there is no inconsistency in the system state (there is -- only produced by callers up the stack). So I catch ArgumentExceptions, log them, send error reports (optionally), recover from those exceptions (fixing inconsistency produced up the stack, if any) and continue running the application.


Yes, maybe you get an ArgumentException because a subsystem (a piece of logic, a function, a feature) is not working in the current release. So be it, maybe we should turn this failing feature off then? -- after we get a certain number of similar exceptions? Yes, this requires a bit of management, domain expertise, and some architectural effort, but I, as a user, fucking hate crashing applications.


Take a text processor for example. Imagine that every time you click «File->Save as…» in the menu, a usage error occurs, an ArgumentException is thrown -- should we close the application and report an error, or can we report the error and continue running the application? I vote for option #2: nothing critical has happened, and I would prefer either just logging the error, reporting it or blocking the erroneous execution path for the release (e.g. by disabling the menu item) to closing the app, losing the document that the user had been editing and then trying to recover it.


P.S. of course, there are ArgumentExceptions indicating that the application is unusable -- it depends on which component throws and under which circumstances.


UPDATE: I have changed my opinion three months after posting this. I do prefer to not catch ArgumentException-s.

No comments:

Post a Comment