Should I catch exceptions in my method for the purpose of "purely documenting", thus encapsulating the documentation of errors within the method itself, or is this the responsibility of the caller?
Suppose in my EncryptPackage() method, including frameworks, I call many other methods that could potentially cause many exceptions. I wrap everything in using blocks, so there is no need to catch exceptions for cleaning (or I use try / finally for cleaning). Should I catch the exception anyway and provide details about the context of this method, or does it depend on the caller’s method?
Here is one case:
[Serializable] class TestClassException : Exception { public TestClassException() : base() { } public TestClassException(string message) : base(message) { } public TestClassException(string message, Exception innerException) : base(message, innerException) { } } class TestClass { public TestClass() { } public void EncryptPackage() { try { DoSomething(); DoAnotherThing(); } catch (Exception ex) { throw new TestClassException("Error occurred during package encryption", ex); } } } class ConsumerExample { public ConsumerExample() { } public void DoSomeStuff() { TestClass testClass = new TestClass(); try { testClass.EncryptPackage(); } catch (TestClassException ex) { System.Windows.Forms.MessageBox.Show(ex.ToString()); } } }
In this code, notice how the EncryptPackage() method detects all possible exceptions, simply "decorates the error text", with the text "Error while processing the package." EncryptPackage() here encapsulates the error description logic.
And here is another technique:
class TestClass2 { public TestClass2() { } public void EncryptPackage() { DoSomething(); DoAnotherThing(); } } class ConsumerExample2 { public ConsumerExample2() { } public void DoSomeStuff() { TestClass testClass = new TestClass(); try { testClass.EncryptPackage(); } catch (Exception ex) { System.Windows.Forms.MessageBox.Show("Error occurred during package encryption.\r\n\r\n" + ex.ToString()); } } }
In this example, EncryptPackage() will not catch anything, because the calling document still documents an error case with the message "An error occurred while encrypting the packet. \ R \ n \ r \ n".
Please note that this is a very simplified example, in the real world there will be many hierarchical classes, and exceptions will be propagated through the stack of a long call, so which method of catching exceptions is preferred? The second approach seems to be “cleaner”, because the exception is handled in the layer where some “actual processing” will be performed (for example, display to the user). The call stack information will be stored in the exception object, so it will technically be possible to find out exactly where the exception was selected. But ... this does not look like a “good documentation” as the first approach, where each level of abstraction adds its own description to the error, storing the previous exception in the innerException member. In this case, when the execution leaves the TestClass layer, it already contains a detailed description of the error that occurred in this class. Thus, it becomes the best encapsulation of error handling logic.
Which one to use?