@danixdefcon5 said:my code throws a couple of specific Exceptions (such as FailedPaymentException)
From the name of it, that doesn't sound like something you want to throw, or even use an exception for.
I mean, let's say your application is an accountant guy who gets things done, and something like a payment fails; do you want him to start screaming, drop to the floor and shit his pants forcing him to cease all work, OR do you want him to notice it, think of a course of action, come to your desk, calmly yet firmly explain the situation, then walk away and continue with the things he had to do?
But perhaps I misunderstand how you let the program handle things.
I'd rather he notice that something went wrong, stop doing what he was about to do (since he can't do it anymore), let me know about it, and let me decide what I want to do about it. Keep the logic of what to do when the payment fails out of the payment processor itself, since you may want different things based on what context it's being called in.
For example, let's say that I have an application that has two different ways of processing payments, one at a time through a web interface, or nightly in unattended batches. Let's say that the method processPayment() returns a confirmation number if it succeeds or throws a FailedPaymentException when something goes wrong. The web client that calls it can display a formatted error message to the user and let them verify their data and try again. The batch job can loop through the batched payments, catch any exceptions thrown in an array, generate a report showing the transaction numbers for processed payments and a separate list of the failed payments, and send an E-mail message with that report attached.
By keeping the what-to-do-on-failure logic out of the method that tries to do a concrete task, you keep that method simple and unit-testable. If you add another way that a user can initiate a payment process (say, through a GUI), you don't have to add more special cases to processPayment(). Instead, you handle failure in the GUI.