Best Practices: Throwing Exceptions from Properties

Best practices: throwing exceptions from properties

Microsoft has its recommendations on how to design properties at http://msdn.microsoft.com/en-us/library/ms229006.aspx

Essentially, they recommend that property getters be lightweight accessors that are always safe to call. They recommend redesigning getters to be methods if exceptions are something you need to throw. For setters they indicate that exceptions are an appropriate and acceptable error handling strategy.

For indexers, Microsoft indicates that it is acceptable for both getters and setters to throw exceptions. And in fact, many indexers in the .NET library do this. The most common exception being ArgumentOutOfRangeException.

There are some pretty good reasons why you don't want to throw exceptions in property getters:

  • Because properties "appear" to be fields, it is not always apparent that they can throw a (by-design) exception; whereas with methods, programmers are trained to expect and investigate whether exceptions are an expected consequence of invoking the method.
  • Getters are used by a lot of .NET infrastructure, like serializers and databinding (in WinForms and WPF for example) - dealing with exceptions in such contexts can rapidly become problematic.
  • Property getters are automatically evaluated by debuggers when you watch or inspect an object. An exception here can be confusing and slow down your debugging efforts. It's also undesirable to perform other expensive operations in properties (like accessing a database) for the same reasons.
  • Properties are often used in a chaining convention: obj.PropA.AnotherProp.YetAnother - with this kind of syntax it becomes problematic to decide where to inject exception catch statements.

As a side note, one should be aware that just because a property is not designed to throw an exception, that doesn't mean it won't; it could easily be calling code that does. Even the simple act of allocating a new object (like a string) could result in exceptions. You should always write your code defensively and expect exceptions from anything you invoke.

What exception to throw from a property setter?

Have a look through mscorlib.dll with Reflector, in a similar situation such as System.String.StringBuilder.Capacity Microsoft use ArgumentOutOfRangeException() similar to:

public int PropertyA
{
get
{
return //etc...
}
set
{
if (condition == true)
{
throw new ArgumentOutOfRangeException("value", "/* etc... */");
}
// ... etc
}
}

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.

By design should a property getter ever throw an exception in python?

After more reading and coming back to this I am going to answer my own question and say no - this is not recommended based on the PEP 8 Style Guide.

https://www.python.org/dev/peps/pep-0008/

Note 3: Avoid using properties for computationally expensive operations;
the attribute notation makes the caller believe that access is (relatively)
cheap.

I realise this is paraphrasing Christian's answer somewhat - but I was looking for some kind of official documentation or guidance on this kind of pattern.

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

How using try catch for exception handling is best practice

My exception-handling strategy is:

  • To catch all unhandled exceptions by hooking to the Application.ThreadException event, then decide:

    • For a UI application: to pop it to the user with an apology message (WinForms)
    • For a Service or a Console application: log it to a file (service or console)

Then I always enclose every piece of code that is run externally in try/catch :

  • All events fired by the WinForms infrastructure (Load, Click, SelectedChanged...)
  • All events fired by third party components

Then I enclose in 'try/catch'

  • All the operations that I know might not work all the time (IO operations, calculations with a potential zero division...). In such a case, I throw a new ApplicationException("custom message", innerException) to keep track of what really happened

Additionally, I try my best to sort exceptions correctly. There are exceptions which:

  • need to be shown to the user immediately

  • require some extra processing to put things together when they happen to avoid cascading problems (ie: put .EndUpdate in the finally section during a TreeView fill)

  • the user does not care, but it is important to know what happened. So I always log them:

  • In the event log

  • or in a .log file on the disk

It is a good practice to design some static methods to handle exceptions in the application top level error handlers.

I also force myself to try to:

  • Remember ALL exceptions are bubbled up to the top level. It is not necessary to put exception handlers everywhere.
  • Reusable or deep called functions does not need to display or log exceptions : they are either bubbled up automatically or rethrown with some custom messages in my exception handlers.

So finally:

Bad:

// DON'T DO THIS; ITS BAD
try
{
...
}
catch
{
// only air...
}

Useless:

// DON'T DO THIS; IT'S USELESS
try
{
...
}
catch(Exception ex)
{
throw ex;
}

Having a try finally without a catch is perfectly valid:

try
{
listView1.BeginUpdate();

// If an exception occurs in the following code, then the finally will be executed
// and the exception will be thrown
...
}
finally
{
// I WANT THIS CODE TO RUN EVENTUALLY REGARDLESS AN EXCEPTION OCCURRED OR NOT
listView1.EndUpdate();
}

What I do at the top level:

// i.e When the user clicks on a button
try
{
...
}
catch(Exception ex)
{
ex.Log(); // Log exception

-- OR --

ex.Log().Display(); // Log exception, then show it to the user with apologies...
}

What I do in some called functions:

// Calculation module
try
{
...
}
catch(Exception ex)
{
// Add useful information to the exception
throw new ApplicationException("Something wrong happened in the calculation module:", ex);
}

// IO module
try
{
...
}
catch(Exception ex)
{
throw new ApplicationException(string.Format("I cannot write the file {0} to {1}", fileName, directoryName), ex);
}

There is a lot to do with exception handling (Custom Exceptions) but those rules that I try to keep in mind are enough for the simple applications I do.

Here is an example of extensions methods to handle caught exceptions a comfortable way. They are implemented in a way they can be chained together, and it is very easy to add your own caught exception processing.

// Usage:

try
{
// boom
}
catch(Exception ex)
{
// Only log exception
ex.Log();

-- OR --

// Only display exception
ex.Display();

-- OR --

// Log, then display exception
ex.Log().Display();

-- OR --

// Add some user-friendly message to an exception
new ApplicationException("Unable to calculate !", ex).Log().Display();
}

// Extension methods

internal static Exception Log(this Exception ex)
{
File.AppendAllText("CaughtExceptions" + DateTime.Now.ToString("yyyy-MM-dd") + ".log", DateTime.Now.ToString("HH:mm:ss") + ": " + ex.Message + "\n" + ex.ToString() + "\n");
return ex;
}

internal static Exception Display(this Exception ex, string msg = null, MessageBoxImage img = MessageBoxImage.Error)
{
MessageBox.Show(msg ?? ex.Message, "", MessageBoxButton.OK, img);
return ex;
}


Related Topics



Leave a reply



Submit