I was wondering what kind of exception should one throw for missing data. For example if an xml node doesn't contain data. It would be easy to "throw new Exception(...)" but this is not recommended. Another option would be to create a new exception class like MissingDataException or InvalidDataException but isn't there a built-in exception class for this case?
As a rule of thumb, check the existing .NET framework exceptions for a suitable exception to throw before deriving your own. To answer your question directly, there is no "missing data" exception currently available to throw, but that doesn't mean there aren't suitable exceptions to cover your situation.
In your case, the humble InvalidOperationException may be suitable; this exception is thrown when you call a method on an object, but the object's state is not appropriate for the operation. Examples of this include calling methods on a closed stream and an enumerator that has passed the end of the collection. If the XML data is the internal state of an object, and a method call has discovered the bad data, InvalidOperationException is a good candidate.
If you are passing your XML data to a method, an ArgumentException, or one of its derivatives may be an appropriate choice. There is a small family of these exceptions, all indicating that an argument passed to a method is not as the method expected.
You will only want to create a custom exception when you want the exceptional circumstance to be handled differently from other exceptions. If you do choose to create your own exception, be sure to derive it from a higher exception than Exception, so that the nature of the exception is implied by the base class.
There is also System.Data.ObjectNotFoundException class which you may consider.
Update: As of Entity Framework 6, this exception class' fully qualified name is System.Data.Entity.Core.ObjectNotFoundException.
See this question for further details on EF5->EF6 namespace changes.
Do not call "throw new Exception", because you don't know how to handle the exception.
Define your own exception. Be more specific, such as XMLDataMissingException. Then you can give a meamingful message to user or log it.
For a general missing data scenario, where the data is referenced by a unique ID, then the KeyNotFoundException might be appropriate - e.g.
throw new KeyNotFoundException($"Expected record for key {key} not found.");
It is in the System.Collections.Generic namespace.
You can use System.Xml.XmlException.
Edit : Even if System.Xml.XmlException could fit, I think you should define your own exception, as it would be more precise, and you could describe what kind of data is missing : an id, a date, etc.
As a rule of thumb you should throw exceptions in Exceptional Circumstances. If the data in question adversely affects the object’s state or behaviour then throw a custom exception. An alternative approach might involve some kind of validator that fires events which your client handles gracefully, for example, report the error to end-user or insert default values.
I had a similar problem you described in which I had 2 clients (call them A & B) reading and modifying a single xml file. Client A deleted node X then Client B attempted to update node X. Clearly, updating a node that no longer exists is a problem. To solve this problem I took inspiration from SQL Server which reports the number of rows affected by an UPDATE statement. In this particular case I raised the UpdateNode event as normal with a number of rows affected property set to zero.
InvalidDataException actually exists. It's in the System.IO namespace.
MSDN
IMO, it's more appropriate than ArgumentException or another boneheaded exception type.
Also, I strongly suggest that you use messages to describe which data is missing, what was the expected value, etc...
throw new Exception("my message"); (or other built in Exception) is often the correct approach. The alternative is an explosion of Exception classes that may only get used once.
If new Exceptions are warranted they should be created in the context of the domain, not the problem.
Related
I'm sure I've seen this in various exception messages in the framework. I checked the following pages from the MSDN library but could not find much guidance for the message contents:
Exception Throwing
Error Message Design
Exception.Message Property
The only part in the first page that could explain it is this text:
Do not disclose security-sensitive information in exception messages
without demanding appropriate permissions.
It's the the ArgumentException thrown by Dictionary<TKey, TValue>.Add method that reminded me of this issue. It looks like this:
System.ArgumentException : An item with the same key has already been added.
Why does it not look something like this?
System.ArgumentException : An item with the same key(123) has already been added.
This assumes 123 is the TKey value, basically any format with the TKey value is what I would thing would be useful to track down an error while debugging.
Is there a known reason why this is not included?
Would it be considered bad practice to re-thrown the argument exception with the key in the message? I had considered making my own exception subclass but I think this is a case where using a built in exception class seems like a better option.
As a rule of thumb, exceptional situations in frameworks want to avoid creating new exceptional situations. To format the message like this:
System.ArgumentException : An item with the same key(123) has already been added.
One would have to assume there is a valid implementation of toString on the key parameter. But what if it is null? Or if it is a custom key that throws a new exception in its toString? Or even some idiot implemented a toString method that throws a random exception 1 out of 10 times? What if the internal exception was caused by an out of memory situation and the conversion would just trigger it again? It would give more unpredictable results than just reporting what it is sure to be able to report.
It looks like a security precaution. The program could be working with security-sensitive data, which it takes care not to write into log messages or reveal through the UI. But, oops, there is a problem and an unhandled exception goes off, where some default handler displays or logs pieces of that sensitive information because it was included in the exception text.
Consider the case where a configuration (a property, in my case) is null.
public Configuration {get;set;}
if (configuration == null)
{
throw NullReferenceException("Blah blah blah..");
}
But, I read somewhere, "Dont ever throw a null reference exception in your code. NullReferenceException is a runtime exception and should only be raised by the runtime".
If it had been a argument of a function, I thought I would use a ArgumentNullException.
So, what should be the exception in this case? And speaking in general, what exceptions should be thrown at what situations? Googled this but no satisfying answers.
InvalidOperationExceptions states - The exception that is thrown when a method call is invalid for the object's current state ,which isn't a bad fit I suppose? I agree that a null reference isn't what you should throw.
here's another list of common exceptions.
The advice is correct, because a null reference exception doesn't say anything about what's actually wrong.
If the value isn't allowed to be null, then you should try to find an exception that describes what's wrong. The problem isn't that the reference is null, but the underlying reason why the reference is null.
If you can't find any exception class that is close enough, you could for example create your own ConfigurationMissingException exception.
InvalidOperationException
The exception that is thrown when a method call is invalid for the object's current state.
Which sounds like your situation.
Basically, if it's not argument related, and you want to throw a built-in exception, your choices usually come down to one of two exceptions. If you'll never be able to honor the request, NotImplementedException is appropriate. But if it's a matter of configuration or state, InvalidOperationException fits the bill.
You should throw no exceptions at what case. It only uses if happens something unexpected like you try set some null value to Configuration.
But if Configuration can be null and it already is, you should handle it out in other way.
I think there are actually three cases here:
Firstly, can this happen as a result of the user of the class doing things wrongly? Did they forget to call or set something first (i.e. is there a temporal dependency that they violated)?
If so, then I think the appropriate exception is either an InvalidOperationException, with a Message that describes how to fix the problem, or perhaps you might want to specify a Code Contract as described below.
Secondly, can this only happen due to a logic bug in the class? In other words, should it be impossible for this to happen no matter how the user of the class uses its public methods and properties?
If so, then if you are using Code Contracts you can declare this to be the case by stating:
Contract.Assume(configuration != null);
I find this to be much better. However, the exception thrown by a violation is uncatchable other than if you catch Exception. This is deliberate, and the right choice IMO.
If you're not using code contracts, then you're stuck with throwing InvalidOperationException.
Thirdly, if this exception arises naturally because of external factors outside the program's control, you should probably write a custom exception type for it if there is no existing one which matches the problem. However, for this particular example it seems unlikely that this is the case. I would expect it to be handled elsewhere.
I have a standalone application that does data checking of flat files before they are imported into a SQL database.
In a context like this, does it make sense to throw a System.Data.ConstraintException? (The example is contrived.)
if(_keys.ContainsKey(key))
{
throw new ConstraintException(string.Format("Uniqueness violated! " +
"This unique combination of '{0}' already found on line {1}",
GetUniquenessColumnList(), _keys[key] ));
}
ConstraintException's documentation states that it "represents the exception that is thrown when attempting an action that violates a constraint."
Is there a problem with using the built-in exception this way? Is there a better one to use? Should I build my own, even though this exception seems tailor-made to my situation?
I think you've answered your own question
...this exception seems tailor-made to my situation?
Why reinvent the wheel?
EDIT:
Check out this MSDN article: Choosing the Right Type of Exception to Throw
Consider throwing existing exceptions residing in the System
namespaces instead of creating custom exception types.
...
Do not create and throw new exceptions just to have your team's exception.
No, there's no problem with doing that. No need to create a new exception if a suitable one already exists.
I have read a few of the other questions regarding C# Exception Handling Practices but none seem to ask what I am looking for.
If I implement my own custom Exception for a particular class or set of classes. Should all errors that relate to those classes be encapsulated into my exception using inner exception or should I let them fall through?
I was thinking it would be better to catch all exceptions so that the exception can be immediately recognized from my source. I am still passing the original exception as an inner exception. On the other hand, I was thinking it would be redundant to rethrow the exception.
Exception:
class FooException : Exception
{
//...
}
Option 1: Foo encasulates all Exceptions:
class Foo
{
DoSomething(int param)
{
try
{
if (/*Something Bad*/)
{
//violates business logic etc...
throw new FooException("Reason...");
}
//...
//something that might throw an exception
}
catch (FooException ex)
{
throw;
}
catch (Exception ex)
{
throw new FooException("Inner Exception", ex);
}
}
}
Option 2: Foo throws specific FooExceptions but allows other Exceptions to fall through:
class Foo
{
DoSomething(int param)
{
if (/*Something Bad*/)
{
//violates business logic etc...
throw new FooException("Reason...");
}
//...
//something that might throw an exception and not caught
}
}
Based on my experience with libraries, you should wrap everything (that you can anticipate) in a FooException for a few reasons:
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.)
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.
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.
Have a look at this MSDN-best-practises.
Consider to use throw instead of throw ex if you want to re-throw caught exceptions, because on this way the original stacktrace keeps preserved(line numbers etc.).
I always add a couple of properties when creating a custom exception. One is user name or ID. I add a DisplayMessage property to carry text to be displayed to the user. Then, I use the Message property to convey technical details to be recorded in the log.
I catch every error in the Data Access Layer at a level where I can still capture the name of the stored procedure and the values of the parameters passed. Or the inline SQL. Maybe the database name or partial connection string (no credentials, please). Those may go in Message or in their own new custom DatabaseInfo property.
For web pages, I use the same custom exception. I'll put in the Message property the form information -- what the user had entered into every data entry control on the web page, the ID of the item being edited (customer, product, employee, whatever), and the action the user was taking when the exception occurred.
So, my strategy as per your question is: only catch when I can do something about the exception. And quite often, all I can do is log the details. So, I only catch at the point where those details are available, and then rethrow to let the exception bubble up to the UI. And I retain the original exception in my custom exception.
The purpose of custom exceptions is to provide detailed, contextual information to the stacktrace to aid in debugging. Option 1 is better because without it, you don't get the "origin" of the exception if it occurred "lower" in the stack.
if you run the code snippet for 'Exception' in Visual Studio you have a template of a good practice exception writing.
Note
Option 1: your throw new FooException("Reason..."); won't be caught as it's outside try / catch block
You should be only catching exceptions that you want to process.
If you're not adding any additional data to the exception than use throw; as it won't kill your stack. In Option 2 you still might do some processing inside catch and just call throw; to rethrow original exception with original stack.
The most important thing for code to know when catching an exception, which is unfortunately completely missing from the Exception object, is the state of the system relative to what it "should" be (presumably the exception was thrown because there was something wrong). If an error occurs in a LoadDocument method, presumably the document didn't load successfully, but there are at least two possible system states:
The system state may be as though the load were never attempted. In this case, it would be entirely proper for the application to continue if it can do so without the loaded document.
The system state may be sufficiently corrupted that the best course of action would be to save what can be saved to 'recovery' files (avoid replace the user's good files with possibly-corrupt data) and shut down.
Obviously there will often be other possible states between those extremes. I would suggest that one should endeavor to have a custom exception which explicitly indicates that state #1 exists, and possibly one for #2 if foreseeable but unavoidable circumstances may cause it. Any exceptions which occur and will result in state #1 should be wrapped in an exception object indicating state #1. If exceptions can occur in such a fashion that the system state might be compromised, they should either be wrapped as #2 or allowed to percolate.
Option 2 is best. I believe best practice is to only catch exceptions when you plan to do something with the exception.
In this case, Option 1 just is wrapping an exception with your own exception. It adds no value and users of your class can no longer just catch ArgumentException, for example, they also need to catch your FooException then do parsing on the inner exception. If the inner exception is not an exception they are able to do something useful with they will need to rethrow.
I was digging around in MSDN and found this article which had one interesting bit of advice: Do not have public members that can either throw or not throw exceptions based on some option.
For example:
Uri ParseUri(string uriValue, bool throwOnError)
Now of course I can see that in 99% of cases this would be horrible, but is its occasional use justified?
One case I have seen it used is with an "AllowEmpty" parameter when accessing data in the database or a configuration file. For example:
object LoadConfigSetting(string key, bool allowEmpty);
In this case, the alternative would be to return null. But then the calling code would be littered with null references check. (And the method would also preclude the ability to actually allow null as a specifically configurable value, if you were so inclined).
What are your thoughts? Why would this be a big problem?
I think it's definitely a bad idea to have a throw / no throw decision be based off of a boolean. Namely because it requires developers looking at a piece of code to have a functional knowledge of the API to determine what the boolean means. This is bad on it's own but when it changes the underlying error handling it can make it very easy for developers to make mistakes while reading code.
It would be much better and more readable to have 2 APIs in this case.
Uri ParseUriOrThrow(string value);
bool TryParseUri(string value, out Uri uri);
In this case it's 100% clear what these APIs do.
Article on why booleans are bad as parameters: http://blogs.msdn.com/jaredpar/archive/2007/01/23/boolean-parameters.aspx
It's usually best to choose one error handling mechanism and stick with it consistently. Allowing this sort of flip-flop code can't really improve the life of developers.
In the above example, what happens if parsing fails and throwOnError is false? Now the user has to guess if NULL if going to be returned, or god knows...
True there's an ongoing debate between exceptions and return values as the better error handling method, but I'm pretty certain there's a consensus about being consistent and sticking with whatever choice you make. The API can't surprise its users and error handling should be part of the interface, and be as clearly defined as the interface.
It's kind of nasty from a readabilty standpoint. Developers tend to expect every method to throw an exception, and if they want to ignore the exception, they'll catch it themselves. With the 'boolean flag' approach, every single method needs to implement this exception-inhibiting semantic.
However, I think the MSDN article is strictly referring to 'throwOnError' flags. In these cases either the error is ignored inside the method itself (bad, as it's hidden) or some kind of null/error object is returned (bad, because you're not using exceptions to handle the error, which is inconsistent and itself error-prone).
Whereas your example seems fine to me. An exception indicates a failure of the method to perform its duty - there is no return value. However the 'allowEmpty' flag changes the semantics of the method - so what would have been an exception ('Empty value') is now expected and legal. Plus, if you had thrown an exception, you wouldn't easily be able to return the config data. So it seems OK in this case.
In any public API it is really a bad idea to have two ways to check for a faulty condition because then it becomes non-obvious what will happen if the error occurs. Just by looking at the code will not help. You have to understand the semantics of the flag parameter (and nothing prevents it from being an expression).
If checking for null is not an option, and if I need to recover from this specific failure, I prefer to create a specific exception so that I can catch it later and handle it appropriately. In any other case I throw a general exception.
Another example in line with this could be set of TryParse methods on some of the value types
bool DateTime.TryParse(string text, out DateTime)
Having a donTThrowException parameter defeats the whole point of exceptions (in any language). If the calling code wants to have:
public static void Main()
{
FileStream myFile = File.Open("NonExistent.txt", FileMode.Open, FileAccess.Read);
}
they're welcome to (C# doesn't even have checked exceptions). In Java the same thing would be accomplished with:
public static void main(String[] args) throws FileNotFoundException
{
FileInputStream fs = new FileInputStream("NonExistent.txt");
}
Either way, it's the caller's job to decide how to handle (or not) the exception, not the callee's.
In the linked to article there is a note that Exceptions should not be used for flow of control - which seems to be implied in the example questsions. Exceptions should reflect Method level failure. To have a signature that it is OK to throw an Error seems like the design is not thought out.
Jeffrey Richters book CLR via C# points out - "you should throw an exception when the method cannot complete its task as indicated by its name".
His book also pointed out a very common error. People tend to write code to catch everything (his words "A ubiquitous mistake of developers who have not been properly trained on the proper use of exceptions tend to use catch blocks too often and improperly. When you catch an exception, you're stating that you expected this exception, you understand why it occurred, and you know how to deal with it.")
That has made me try to code for exceptions that I can expect and can handle in my logic otherwise it should be an error.
Validate your arguments and prevent the exceptions, and only catch what you can handle.
I would aver that it's often useful to have a parameter which indicates whether a failure should cause an exception or simply return an error indication, since such a parameters can be easily passed from an outer routine to an inner one. Consider something like:
Byte[] ReadPacket(bool DontThrowIfNone) // Documented as returning null if none
{
int len = ReadByte(DontThrowIfNone); // Documented as returning -1 if nothing
if (len
If something like a TimeoutException while reading the data should cause an exception, such exception should be thrown within the ReadByte() or ReadMultiBytesbytes(). If, however, such a lack of data should be considered normal, then the ReadByte() or ReadMultiBytesbytes() routine should not throw an exception. If one simply used the do/try pattern, a the ReadPacket and TryReadPacket routines would need to have almost identical code, but with one using Read* methods and the other using TryRead* methods. Icky.
It may be better to use an enumeration rather than a boolean.