Exception order when multiple are possible
If a function has 2 arguments and both produce exceptions, what order would you have them raised in and where would you define it?
This came up when I was writing a test for a function that 开发者_如何学Pythonwould take a directory on disk and compress it into a file. For instance:
void Compress(string dirPath, string filePath);
I haven't written the function yet and I'm putting my tests in place.
The thing is, if the directory path doesn't exist I'd have an exception for a missing directory thrown and if the file had write permissions in the way I'd have an exception thrown to show that. However, what if both paths would cause exceptions? Would I throw the first, the second, another third one, or is it an unknown state? We'd also considered having a single exception to say "Something broke", but the message would be different in each case so doesn't really help.
I've thought of a few ways around it such as always throwing based upon left to right processing of the arguments, or stating "If dirPath is invalid then X is thrown else if filePath is invalid then Y is thrown" and placing that with the interface definition so that whoever implements it should (hopefully) follow this specification.
Just wondering what approach people would take to this problem.
For reference, this is in C# but I don't think this is a language specific problem.
When determining exception order, you should determine what the logical order of failure would be. So in your example, if the directory doesn't exist and the file write permission isn't allowed, it's not unreasonable to expect that your code will first check for the existence of the directory before attempting to create the target file; therefore, that exception should be thrown from the code which will check for the existence of the directory, which will get done first.
Of course, if you have a specific reason for changing the order of the operations (create write file first, then check source directory), that's perfectly fine; the point is, though, either path will throw an exception, which indicates that SOMETHING went wrong with the operation; how the calling code handles it is up to the calling code. If you want to trap one type of recoverable exception (filenotwritable, for example) and handle that specifically, and then just trap a general exception for everything else, that's fine; your application should define the protocol by which it considers and handles the exceptions of the called code.
I would leave it unspecified. Documentation could say:
Possible exceptions include: X if dirPath is invalid; Y if filePath is invalid.
If there's a unit test where both are invalid, it could pass as long as either of the two exceptions is thrown.
Because really, anything that actually depends on which exception happens when there are multiple exception-worthy problems is not a good idea.
精彩评论