c# – Business logic error handling. Should exceptions really be avoided?

C#’s primary error handling mechanism are exceptions and try pattern.

We don’t have access to discriminated unions yet like in case of F# and Rust Option<T> and Result<T, E> types.

The official Microsoft guidelines mention that exceptions should be avoided for errors that can happen often.

The try pattern works only for non async methods. So it’s not really suitable as most methods in business logic code do some I/O operations and need to be async.

For a single point of failure returning null might make sense but in many cases there is more than 1 point of failure.

Pros of exceptions

  • Can be handled globally in a single place
  • The code doesn’t need to check error status all the time and most importantly you don’t forget to check it (unless you manage to make compile-time checks somehow)

Cons of exceptions

  • Performance overhead
  • You don’t know what exceptions certain method throws if it’s not documented and without looking at the implementation (not explicit)

Considerations and code samples

Imagine a method named AcceptPayment which can have more than one points of failure e.g. InsufficientFunds, UserAccountBlocked etc.

What would be the best way to implement custom exceptions for such cases? There are 2 perhaps more different ways

1. Exception per method with Error enum

public enum AcceptPaymentError 
{
    InsufficientFunds,
    UserAccountBlocked
}

public class AcceptPaymentException : BusinessLogicException
{
    public AcceptPaymentException(AcceptPaymentError error) : base(...)
    {
        Error = error;
    }

    public AcceptPaymentError Error { get; }
}

2 Exception per point of failure

In this case we will have InsufficientFundsException and UserAccountBlockedException deriving directly from BusinessLogicException so it can be used in more than 1 method.

Avoiding exceptions completely and using something temporarily in place of official discriminated union support

This is something I see many developers do nowadays. They don’t use exceptions at all in their core/business logic layer but rely on custom types.

We can either use record and switch expressions or rely on some open source libraries providing partial support for DUs e.g.

What is your view on this subject? Would you use something like OneOf in place of exceptions? Why?

c# – What’s the logic behind the design of exceptions?

“What value is being divided by zero?” is irrelevant – there is no legal value which is allowed to be divided by zero, and even if there were such a value, this information does not look very useful to me in most real-world cases.

“Which Constraint (was violated)?”, however, is encoded in the exception – the type DivideByZeroExcxeption says “the constraint of not using zero as a divisor” was violated.

So for this case, the design of exceptions in C# seem to be fine. Another “common sense” question to ask is “in which line of code did the zero-division occur”, and that is also answerable, by evaluating the StackTrace property.

In your Stackoverflow question, the situation is a little bit different. An InvalidConstraintException could be filled with specific information about the violated constraint using the Message property and the Data property, so the design of the Exception class seems provides the necessary tools. However, if the code which throws this exception does not make use of these properties, then you have to blame the design of that code, not the design of the Exception class for it.

error handling – How can I avoid re-running code when exceptions are thrown and user re-submits?

I have a checkout process that 1) creates a user account in Stripe and my database, 2) creates a paymentMethod in Stripe and logs the last4 in the database, 3) creates the subscription in Stripe and logs the subscription to database, 4) sends welcome email and creates a job record in the database to build the service for the subscription.

However, during this process, a lot can go wrong. Some of the things I can think of are: 1) credit card number is invalid, card is declined, API rate limiting, database server goes down/overloaded, etc…

I’m using a try/catch in PHP. However, how can I avoid re-running parts of the try if the user simply needs to fix some input like using a different card number because the other one declined?

At this point the customer record is already created, so I don’t need to re-run those parts.

try {
- 1
- Create Stripe Payment Method
// this will throw any credit card validation errors such as invalid dates, csc, etc...

- 2
- Create Stripe Customer
- Attach payment method to Customer
- Create record in database for customers table

- 3
- Create Stripe subscription
- Create record in database for subscriptions table

- 4
- Create record in job table to send out welcome email and build service for customer 

- display thank you page
} catch 
- Stripe CreditCard validation
- Stripe API Rate Limit
- Stripe API network error
- other Stripe error handling
- PDO Exceptions
}

Should I create a session variable for each section and use an if block of code to prevent re-running it?

For example if section 2 completes, do something like $_SESSION('customer') = 'done'; and then do:

 if ($_SESSION('customer') == 'done') { 
   // don't run
 } else {
   // run code

    $_SESSION('customer') = 'done';
 }

virus – Return adresses’ processor’s system stack, exceptions’ processor’s system stack and in-method(procedure or function) jumps diapason system stack

virus – Return adresses’ processor’s system stack, exceptions’ processor’s system stack and in-method(procedure or function) jumps diapason system stack – Information Security Stack Exchange

cache – 1 exception(s): Exception #0 (MagentoFrameworkExceptionValidatorException): Invalid template file:

Magento 2.3.4
Noticed some of my menu options are not working and in Cache Management I am now faced with a white screen and lots of errors. I tried to paste the whole thing but this site thinks it is spam and will not let me post. The opening line reads….

‘1 exception(s):
Exception #0 (MagentoFrameworkExceptionValidatorException): Invalid template file: ‘Magento_Backend::system/cache/additional.phtml’ in module: ‘Magento_Backend’ block’s name: ‘cache.additional’

Any help massively appreciated

magento2 – 1 exception(s): Exception #0 (LogicException): Front controller reached 100 router match iterations

I am getting this error that I couldn’t know from where it is generated

1 exception(s):
Exception #0 (LogicException): Front controller reached 100 router match iterations

I think it is coming from
…/dix.ml

SimplifiedMagentoRequestFlowControllerPageRouter
false
61

If anyone has an idea about this error ?

Thanks in advance

object oriented design – Is it bad to use checked exceptions as API response?

Consider the following code:

public class User {
    private String password;

    public void changePassword( String oldPassword,
                                String newPassword) throws WrongOldPasswordException,
                                                    NewPasswordTooWeakException
    {
        if (password != null) {
            if (!password.equals(oldPassword)) {
                throw new WrongOldPasswordException();
            }
        }

        if (newPassword.length() < 4)
            throw new NewPasswordTooWeakException();

        this.password = newPassword;
    }

    public static class WrongOldPasswordException extends Exception {

    }

    public static class NewPasswordTooWeakException extends Exception {

    }
}

With the current API design, my presentation layer knows exactly what to do:

class UserViewController {
    User user;

    void changePassword() {
        String oldPassword = view.getOldPassword();
        String newPassword = view.getNewPassword();
        try {
            user.changePassword(oldPassword, newPassword);
        } catch (WrongOldPasswordException e) {
            view.showOldPasswordDoNotMatch();
        } catch (NewPasswordTooWeakException e) {
            view.showNewPasswordIsWeak();
        }
    }
}

If the changePassword method returns boolean with success/fail, my presentation layer does not know the reason. So, I either use these exceptions, or return some sort of Value Object.

If not checked exceptions (something I read that it is considered “bad practice”), then what?

If I use unchecked exceptions, then the code will be the same but the controller will have to guess for the cause of the exception (Isn’t this worse)?

exceptions – How to provide consistent error feedback without loosing performance?

Imagine you want to read a property of a voting of a question. Since a voting always belongs to a question the REST endpoint might be

GET /questions/1/votings/1

What if either the question or the vote do not exist?

Simply return null

+ No additional validators required

- No way to figure out which one of them doesn't exist

Throw a NotFound exception

+ Improved consumer feedback

- Additional validators required
- No way to figure out which one of them doesn't exist (check the error message for that)
- expensive try/catch statements

Throw a QuestionNotFound or a VotingNotFound exception

+ Best consumer feedback

- Additional validators required
- Big switch case statements to check against the thrown exception
- expensive try/catch statements

I think there are way more comlex scenarios coming up with the same problems. E.g. marking a document as deleted but you can’t because that action would violate a business rule.

One way to get rid of the expensive try/catch statements would be to always return a result that either contains the data or the error and the other one is null. But then you still have to check for it and handle the error in the switch case statement (imagine having hundreds of individual exceptions).

Are there any standardized rules you can use or do you have to look at each case individually? If there is no rule and every handler should choose his own way solving this, how do you ensure that the application remains consistent?

design – Error handling for repository: exceptions or wrapping return value?

The repository pattern is defined as:

REPOSITORY: A mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects.

– Eric Evans in DDD

Getting objects from the repository

Typically, you’d have methods to retrieve items such as getByID() returning a single item, getAll(), or some kind of find() returning a collection of items that match some criteria.

Let’s start with the collection based methods:

  • Suppose that your repository is empty. getAll() would then be expected to return an empty set. This emulates best a collection of objects.

  • Suppose now that you query using some criteria that isn’t met by any record. Again, the most logic return would be an empty collection. If you would return an error insted, you’d risk to be inconsistent: what would you return for a dynamic query that asks for no specific criteria on an empty repository without contracting the equivalent behavior of getAll()?

For the item based getById(). Here the choices are not so clear cut:

  • You could argue that the single item is just a convenience, to avoid working with collections made of a single element. The best option would be to return a null when nothing is found (i.e. similar to an empty set, for no items). This is in particular useful if IDs are managed externally (e.g. provided by user, or meaningful) and if the developers are used to handle the returned result with caution.
  • You could as well argue that getById() is in general used with known IDs and it’s in general assumed that they exist. In this situation a null might be unexpected and generate risks if it is forgotten only once to check the validity of the returned object. In this situation, the best option would be to throw an exception.

So the choice should be driven by the practices and expectation in your context. Personally I have a preference for the null although it requires more discipline.

Changing the content of the repository

Typically you’d have some kind of add(), remove(), and perhaps update() that would change the repository content. When you use these function, you generally expect that they work.

A frequent practice is to have methods with no return value (void). In this case, you have no choice but to raise an exception in case of an unexpected error. This is very practical in fact, if you have to manage transactions that span several repositories, since you can easily catch any error in a transaction and rollback the whole transaction.

But you’ll also find some repository implementations that provide these methods but returning an error code instead. It’s more flexible for error handling, no problem, but if most of the time you need to check the error code and raise an exception to rollback some transactions, you’ll end-up wiht lot of boiler-plate code.

The folowing strong arguments are in favor of the first approach:

I personally don’t like these methods to answer Boolean results as do full-fledged collections. That’s because in some cases answering true to an add-type operation does not guarantee success. The true results may still be subject to a transaction commit on the data store. Thus, void may be the more accurate return type in the case of a Repository.

– Vaughn Vernon in Implementing DDD

Your additional question about validation

The scenario that you describe is not crystal clear, and does not seem to be related to the repository pattern itself. Unfortunately we know to little about your specific case and I invite you to formulate a distinct question only focused on that last aspect. Nevertheless here some first thoughts:

Performing validations in the front-end to guide user, but nevertheless doing a thorough validation in the back-end is a very common situation (You cannot rely on front-end validation for ensuring corporate consistency).

An error in the back-end validation does not fatally have to cause user entry to get lost. You may probably structure the interaction in such a way to inform the user of the back-end problem and propose to edit/resubmit the data. THere are more tricky strategies to cope with concurrency errors.

Java validation void exceptions vs Boolean check

I was reading this question Is it better practice to have void method throw an exception or to have the method return a boolean? that was asked a while ago and I’m faced with a similar dilemma.

Since I’m using logs to print how the validation process is going and I have multiple fields to validate it just seems cleaner to me to use voids that will print logs and validate fields (throw exceptions when not valid) rather then making methods return a boolean and in the main method print logs and throw exception. It seems to me that the main method will be way too cluttered and long.

Example of what I mean

Void Exception Validation

void validate() {
    //pre-logic

    validateThis();
    validateThat();

    //post-logic
}

void validateThis() {
    //log start
    //throw exception if fail
    //log end
}

void validateThat() {
    //log start
    //throw exception if fail
    //log end
}

Boolean Checking

void validate() {
    //pre-logic

    //log start
    if(validateThis()) {
        //throw exception
    }
    //log end
    
    //log start
    if(validateThat()) {
        //throw exception
    }
    //log end

    //post-logic
}

boolean validateThis() {
    //return false or true
}

boolean validateThat() {
    //return false or true
}

It should be noted I never expect to call validateThis() or validateThat() anywhere else in my code and these fields are necessary for the application to keep going, they cannot be invalid.

Is void exception validation still considered poor practice?

Thank you!

DreamProxies - Cheapest USA Elite Private Proxies 100 Cheapest USA Private Proxies Buy 200 Cheap USA Private Proxies 400 Best Private Proxies Cheap 1000 USA Private Proxies 2000 USA Private Proxies 5000 Cheap USA Private Proxies ExtraProxies.com - Buy Cheap Private Proxies Buy 50 Private Proxies Buy 100 Private Proxies Buy 200 Private Proxies Buy 500 Private Proxies Buy 1000 Private Proxies Buy 2000 Private Proxies Proxies123.com