C#: Throwing Custom Exception Best Practices

What are industry standard best practices for implementing custom exceptions in C#?

The standard for creating custom exceptions is to derive from Exception. You can then introduce your own properties/methods and overloaded constructors (if applicable).

Here is a basic example of a custom ConnectionFailedException which takes in an extra parameter which is specific to the type of exception.

[Serializable]
public class ConnectionFailedException : Exception
{
public ConnectionFailedException(string message, string connectionString)
: base(message)
{
ConnectionString = connectionString;
}

public string ConnectionString { get; private set; }
}

In the application this could be used in scenarios where the application is attempting to connect to a database e.g.

try
{
ConnectToDb(AConnString);
}
catch (Exception ex)
{
throw new ConnectionFailedException(ex.Message, AConnString);
}

It's up to you to then handle the ConnectionFailedException at a higher level (if applicable)

Also have a look at Designing Custom Exceptions and Custom Exceptions

C#: Throwing Custom Exception Best Practices

Based on my experience with libraries, you should wrap everything (that you can anticipate) in a FooException for a few reasons:

  1. People know it came from your classes, or at least, their usage of them. If they see FileNotFoundException they may be looking all over for it. You're helping them narrow it down. (I realize now that the stack trace serves this purpose, so maybe you can ignore this point.)

  2. You can provide more context. Wrapping an FNF with your own exception, you can say "I was trying to load this file for this purpose, and couldn't find it. This hints at possible correct solutions.

  3. Your library can handle cleanup correctly. If you let the exception bubble, you're forcing the user to clean up. If you've correctly encapsulated what you were doing, then they have no clue how to handle the situation!

Remember to only wrap the exceptions you can anticipate, like FileNotFound. Don't just wrap Exception and hope for the best.

Is this good practice for a Custom Exception?

I decided to rewrite my answer to be specific to your actual question, and in a more broad sense that an MVC application isn't the only thing these best-practices apply to.

(1) Answer. This is not good practice. You should use a exception builder method instead that throws HttpException directly.

public static void ThrowPageNotFoundException() {
throw new HttpException((Int32)HttpStatusCode.NotFound, "HTTP/1.1 404 Not Found");
}

(2) DO. Use exception builder methods (eg. the code I provided). This allows for you to avoid the extra performance cost of having your own exception type, and allows for it to be inlined. Members throwing exceptions do not get inlined. This would be the proper substitute for convenience throwing.

(3) DO. Use base class library exceptions whenever possible, and only create a custom exception when there is absolutely no base exception that meets the needed requirements. Creating custom exceptions adds deeper exception hierarchy, which makes debugging harder when it does not need to be, adds extra performance overhead, and also adds extra bloat to your code base.

(4) Do NOT. Throw the base class System.Exception. Use a specific exception type instead.

(5) Do NOT. Create custom exceptions for convenience. This is not a good reason for a custom exception, because exceptions are intrinsically costly.

(6) Do NOT. Create custom exceptions just to have your own exception type.

(7) Do NOT. Throw exceptions that can be avoided by changing the calling code. This would suggest that you have a usability error in the API rather than an actual problem.

Anyone who has read Framework Design Guidelines from the .NET development series will know these practices, and they are very good practices. These are the very practices that the .NET framework was built upon, and MVC as well.

Is it a good practice to throw exceptions?

I'm sure this question had been answered elsewhere. But here are a few other links for reading:

  • Best practices for catching and re-throwing .NET exceptions
  • When to throw an exception?

From the book "The Pragmatic Programmer", the big question relating to the usage of exceptions is "What is Exceptional?".

In that section, I quote:

... exceptions should rarely be used as part of a program's normal flow; exception should be reserved for unexpected events.

While it is debatable whether or not to use exception in your case, I would say no - because you probably need to capture all possible input errors in one request and reflect back on the form for the user to correct those values.

Now that I recall, yes you should use exceptions here. This is how you code defensively. If you already expected valid arguments to be passed into the Customer class, then the code should throw exception to guard against invalid usage of the class (say for example, by another programmer). In that case, you should have another input validator to validate user's input to the application before reaching the Customer class.

C#, usage of custom exceptions

While normally I'd suggest that a question like this should be closed as opinion-based, in this case there's really clear guidance from Microsoft:

Use the predefined .NET exception types

Introduce a new exception class only when a predefined one doesn't apply. For example:

  • Throw an InvalidOperationException exception if a property set or method call is not appropriate given the object's current state.

  • Throw an ArgumentException exception or one of the predefined classes that derive from ArgumentException if invalid parameters are passed.

In other words, your customer is asking you to go against guidance from the platform authors.

You may not be able to change the customer's mind to follow the guidance, but you can be confident that your approach is the recommended one, and their approach goes against that.

Following conventions like this is particularly important in Open Source projects - it's one thing to decide that you'll have your own conventions when only your team will work with the code, but if an application uses 10 different Open Source libraries, each of which has decided to create its own conventions, that's a nightmare.

Custom Exception C#

  1. In this case it is more appropriate to throw ArgumentNullException instead. Which exception you end up using (your own or ArgumentNullException) does not matter and does not change the structure of the code below OR how you should handle an Exception.
  2. You want to check value, not name in the setter.
  3. Handle the exception at the calling code. If the calling code is not designed to handle the Exception then do not catch that Exception OR rethrow using throw to preserve the stack trace.
  4. Throw the exception at the location where the code fails due to... (invalid value in this case)
  5. Be careful with your getter/setter code, you were checking the wrong values and also bypassing the setter in the constructor in which case it would never throw an Exception to begin with.

Your Man class.

public class Man {
public Man(string name)
{
// notice capital N for Name so it is set on the property, not the field
// this will execute the setter for the Name property
this.Name = name;
}

public Man(){} // optional, but do not include the parameterized constructor you had as it sets the private fields directly OR include additional validation

private string name;
public string Name
{
get { return name; }
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentNullException("Name cannot be null or empty");
name = value;
}
}
}

Calling code which handles the exception.

try
{
// use parameterized constructor
Man p = new Man("Dan");

// or use an initializer
Man p = new Man{Name = "Dan"};

// the above initializer is actually short for
Man p = new Man();
p.Name = "Dan";
}
catch (ArgumentException e)
{
Console.WriteLine("Error occurred!! Do something...");
}

Is there a way to throw custom exception without Exception class

throw new Exception("A custom message for an application specific exception");

Not good enough?

You could also throw a more specific exception if it's relevant. For example,

throw new AuthenticationException("Message here");

or

throw new FileNotFoundException("I couldn't find your file!");

could work.

Note that you should probably not throw new ApplicationException(), per MSDN.

The major draw back of not customizing Exception is that it will be more difficult for callers to catch - they won't know if this was a general exception or one that's specific to your code without doing some funky inspection on the exception.Message property. You could do something as simple as this:

public class MyException : Exception
{
MyException(int severity, string message) : base(message)
{
// do whatever you want with severity
}
}

to avoid that.

Update: Visual Studio 2015 now offers some automatic implementation of Exception extension classes - if you open the Quick Actions and Refactoring Menu with the cursor on the : Exception, just tell it to "Generate All Constructors".

What's the best practice to structure exception messages?

As Tim mentioned in the comments already localization can be a problem if the messages are shown to users.

What my approach on this topic is, and what I really like to suggest is the following.

Try to make it generic.

Makea a constants class holding your exception Messages with meaningfull constants names like this:

public static const String IN_VARIABLE_MISSING = "An expected value is missing. Please try again";

This will give you the ability to actually re-use the exception wherever it is needed. ( Also you only need to edit it at one place and have it updated everywhere ) You can build a wrapper which will handle the localization. But there are so many options for that topic, that I will not elaborate too much.

So you then can throw an exception like this:

throw new Exception(IN_VARIABLE_MISSING);

If this is software which will be used commercial I would also recommend to write an own Exception which extends the standard Exception.

Why?

You can create an exception that will take your message and an number for example and will automatically build an unique key for you like this:

IN-MODULE-NUMBER-IDENTIFICATION

You see where that could be handy? Excactly in localization and in faster finding of where it happened and why it happened.

You can modify it to write IN at the beginning for Internal errors. VA for validation errors. Then the class/project where it happened and then a number or whatever you want.

This system will also give you the ability to use another string for that key depending on the locale the user is using.

TL;DR Make it reusable!



Related Topics



Leave a reply



Submit