i have some business logic that traps some logically invalid situations, e.g. trying to reverse a transaction that was already reversed. In this case the correct action is to inform the user:
Transaction already reversed
or
Cannot reverse a reversing transaction
or
You do not have permission to reverse transactions
or
This transaction is on a session that has already been closed
or
This transaction is too old to be reversed
The question is, how do i communicate these exceptional cases back to the calling code, so they can show the user?
Do i create a separate exception for each case:
catch (ETransactionAlreadyReversedException)
MessageBox.Show('Transaction already reversed')
catch (EReversingAReversingTransactionException)
MessageBox.Show('Cannot reverse a reversing transaction')
catch (ENoPermissionToReverseTranasctionException)
MessageBox.Show('You do not have permission to reverse transactions')
catch (ECannotReverseTransactionOnAlredyClosedSessionException)
MessageBox.Show('This transaction is on a session that has already been closed')
catch (ECannotReverseTooOldTransactionException)
MessageBox.Show('This transaction is too old to be reversed')
Downside for this is that when there's a new logical case to show the user:
Tranasctions created by NSL cannot be reversed
i don't simply show the user a message, and instead it leaks out as an unhandled excpetion, when really it should be handled with another MessageBox.
The alternative is to create a single exception class:
`EReverseTransactionException`
With the understanding that any exception of this type is a logical check, that should be handled with a message box:
catch (EReverseTransactionException)
But it's still understood that any other exceptions, ones that involve, for example, an memory ECC parity error, continue unhandled.
In other words, i don't convert all errors that can be thrown by the ReverseTransaction() method into EReverseTransactionException, only ones that are logically invalid cause of the user.