4

In many cases in web applications you would need to return an error message, rather than simple true/false result. One would use exceptions for that, but I consider exceptions to be an indication of, you know, exceptional behavior. Let's take a Register() function for a class User for instance. If it was successful we can simply return true, but if something went wrong we would like to know what exactly: "passwords don't match", "e-mail is in invalid format" and so on (could be an error code instead of a message, doesn't matter).

The question is what is the best practice for returning such error messages in C# and .Net? There might be a struct ready, something like:

public struct Result {
    public bool OK;
    public string Message;
}

Or perhaps I should just use a parameter in the function? Like Register(out string Message).

Update. This pretty much describes everything I need: http://blogs.msdn.com/kcwalina/archive/2005/03/16/396787.aspx

1
  • Every time a C# developer uses an output param a small kitten dies Commented Jun 5, 2013 at 15:13

4 Answers 4

3

If it's for validation purposes I would recommend you the excellent Fluent Validation library.

Quote from the site:

using FluentValidation;

public class CustomerValidator: AbstractValidator<Customer> {
  public CustomerValidator() {
    RuleFor(customer => customer.Surname).NotEmpty();
    RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(customer => customer.Company).NotNull();
    RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
    RuleFor(customer => customer.Address).Length(20, 250);
    RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
  }

  private bool BeAValidPostcode(string postcode) {
    // custom postcode validating logic goes here
  }
}

Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);

bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;
Sign up to request clarification or add additional context in comments.

2 Comments

This is great, but it's such a huge overhead when all you need to do is check a few conditions. Considering this link: richarddingwall.name/2009/08/19/… , 6 classes perform something that really should be done in 1 or 2.
In the example I provided in my post there's a single class: CustomerValidator which allows you to keep your validation logic separated. Then all you do is use this class. In the link you provided there are six classes because there are six different things you are accomplishing: MVC controller, Validation, Repostory and the accompanying unit tests, which looks perfectly fine to me.
2

I think exceptions can and should be used here.

You can put your Register() call in a try/catch block therefore preventing application execution stop. In the catch block you will analyze what exactly got wrong and return an appropriate message.

Comments

2

I think exception should be used when it comes to program mistakes and IO communication. This means:

  • non-validated input

  • a bug in the software. (adding 2 equal keys to dictionaries)

  • disk access/network/cross application/ etc

For a Register method i should either use a boolean for result checking.

if(Register("someone", "password"))
{
  // success
}
else
{
  // failed
}

or if you like more details on the result, specify a result enum:

public enum RegisterResult
{
  Success,
  BadUsernamePassword,
  PasswordTooShort
}

RegisterResult result = Register("someone", "password");

switch(result)
{
  case(RegisterResult.Success):
    // success
    break;
  case(RegisterResult.BadUsernamePassword):
    // failed
    break;
  case(RegisterResult.PasswordTooShort):
    // failed
    break;
}

If you need more information like a userId, you should define it as a output parameter

int userId = 0;

RegisterResult result = Register("someone", "password", out userId);

etc...

So if an exception is thrown, this means 1 of 3 things.

  • Some of the input (by user) is not validated. ' (negligence of the programmer)

  • There is bug in it. (like accessing disposed objects or something serious. etc.)

  • There is an IO problem. (connecting lost from database.. etc)

I advice u to use exceptions only in exceptional situations. A bad login isn't an exception, it's a user fault.

Regards, Jeroen

Comments

0

Throwing exceptions creates CPU utilization while adding all call stack and setting other fields of exception class.

I prefer not to throw Exceptions. If it is really casual error like say Argument is null,i would go for struct with an ExceptionMessage field with it.

But it is better to type-value check before calling a method and expecting primitive types to return from the method since you need a boolean value return to.

3 Comments

Yes, i am wrong it is typo. I meant CPU. I was struggling to create best execution plan for my sql query. But, it would rather be helpfull if you simply edit it instead some magical down point :)
@bloparod, instead giving a downvote to help yourself to feel better, you may kindly write down some information why i am wrong than this can help me and everyone that reads that post. This was wrong beacuse i made typo error, John helped me to fix it. What is your cause? Tell me something and i will downvote my self friend. It has been almost a year, but whatever.
@bloparod, You can check some info at onjava.com/pub/a/onjava/2003/11/19/exceptions.html about exception my friend if you need some detailed information.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.