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.
Related
In msdn link, it is mentioned that
Do not throw System.Exception or System.SystemException.
In my code i am throwing like this
private MsgShortCode GetshortMsgCode(string str)
{
switch (str.Replace(" ","").ToUpper())
{
case "QNXC00":
return MsgShortCode.QNXC00;
default:
throw new Exception("Invalid message code received");
}
}
is this a bad practice??
Generally you can be more explicit.
In this case, you can throw a
ArgumentException
The more specific you are, the easier it is for other code to handle the exception.
This allows you to do
try
{
GetshortMsgCode("arg")
}
catch(ArgumentException e)
{
//something specific to handle bad args, while ignoring other exceptions
}
In this specific instance you should be throwing ArgumentException.
The main point of specific exception types is to think about it from the callers perspective. I understand this is actually quite tricky when you are also writing the calling code too as you understand the implementation details on both sides. However, always try and think about how you can provide the caller with enough information to clearly understand what if anything they did wrong.
In this instance simply throwing Exception would mean they would have to parse the error message to understand what they did wrong whereas throwing ArgumentException means they can more easily differentiate in their try/catch between them having passed you something invalid or you having failed to executed correctly for some other reason.
I'm reluctant to use terms like "bad practice" because almost everything is correct in some contexts. But usually, yes, it's considered better to throw the most specific kind of exception that exists for your situation, and if a specific one doesn't exist you should define one.
The reason is that if you throw Exception, your callers can't distinguish between the error you're raising and any other exception that may have been thrown by the system during the call they made to your code.
In many cases the caller might decide to handle your exception differently than other problems, or at least they might log a specific message knowing that your exception occurred. That would be difficult for the caller to achieve if your exception can't easily be distinguished from others.
Which exception should I use when the program reaches a logic state that I "know" won't happen, and if it does, something is terribly bad?
For example:
int SomeFunction(int arg) {
SomeEnum x = Whatever(arg, somePrivateMember);
switch (x) {
case SomeEnum.Value1:
return SomeFunction1();
case SomeEnum.Value1:
return SomeFunction2();
default:
throw new WhatTypeToThrow();
}
}
Clearly, ArgumentException is a long-shot here since the invalid value for x could have come from a bug in Whatever(), or an invalid combination of any arguments and/or the current instance state.
I'm looking for something such as an InvalidProgramStateException, InternalErrorException or similar.
Of course I could define my own, but I wonder if there is a suitable exception in the framework.
Edit: Removed the simple sample code to reduce amount of ArgumentException answers.
What about InvalidOperationException?
Why not the InvalidEnumArgumentException? It looks like it was designed specifically for this use-case.
Don't throw any specific exception type in the code you're looking at. Call Trace.Assert, or in this case even Trace.Fail to get a similar effect to Debug.Assert, except enabled even in release builds (assuming the settings aren't changed).
If the default trace listener, the one that offers a UI that offers to kill the whole program or launch a debugger, isn't appropriate for your needs, set up a custom trace listener in Trace.Listeners that causes a private exception type to be thrown whenever Trace.Fail is called (including when a Trace.Assert fails).
The exception type should be a private exception type because otherwise, callers may be tempted to try catching whatever exception type you're going to throw. For this particular exception type, you will want to make it as clear as possible that a future version of the method will no longer throw this particular exception. You don't want to be forced to throw a TraceFailedException or whatever you call it from now until eternity to preserve backwards compatibility.
Another answer mentioned Code Contracts already as an alternative. It is, in a similar way: you can call Contract.Assert(false). This takes the same approach of making it customisable what happens if an assertion fails, but in this case, the default behaviour is to throw an exception, again of a type that is not externally accessible. To make the most of Code Contracts, however, you should be using the static rewriter, which has both pros and cons that I will not get into here. If for you the pros outweigh the cons, then by all means use it. If you prefer to avoid the static rewriter though, then I'd recommend avoiding the Contract class entirely, since it is not at all obvious which methods do and don't work.
I think ArgumentOutOfRangeException is valid here and it's what I use. It's the argument to the switch statement that is not handled as it's out of the range of handled values. I tend to code it like this, where the message tells it like it is:
switch (test)
{
case SomeEnum.Woo:
break;
case SomeEnum.Yay:
break;
default:
{
string msg = string.Format("Value '{0}' for enum '{1}' is not handled.",
test, test.GetType().Name);
throw new ArgumentOutOfRangeException(msg);
}
}
Obviously the message is to your own tastes, but the basics are in that one. Adding the value of the enum to the message is useful not only to give detail concerning what known enum member was not handled, but also when there is an invalid enum i.e. the old "(666)SomeEnum" issue.
Value 'OhNoes' for enum 'SomeEnum' is not handled.
vs
Value '666' for enum 'SomeEnum' is not handled.
Here are suggestions that I've been given:
ArgumentException: something is wrong with the value
ArgumentNullException: the argument is null while this is not allowed
ArgumentOutOfRangeException: the argument has a value outside of the valid range
Alternatively, derive your own exception class from ArgumentException.
An input is invalid if it is not valid at any time. While an input is unexpected if it is not valid for the current state of the system (for which InvalidOperationException is a reasonable choice in some situations).
See similar question and answer that I was given.
You should consider using Code Contracts to not only throw exceptions in this case, but document what the failed assumption is, perhaps with a friendly message to the programmer. If you were lucky, the function you called (Whatever) would have a Contract.Ensures which would catch this error before you got your hands on it.
program reaches a logic state that I "know" won't happen, and if it does, something is terribly bad.
In this case, I would throw an ApplicationException, log what you can, and exit the app. If things are that screwed up, you certainly shouldn't try to recover and/or continue.
This is the bane of my programming existence. After deploying an application, when this error crops up, no amount of debug dump tells you WHAT object was not instantiated. I have the call stack, that's great, it tells me roughly where the object is, but is there any way to get .NET to tell me the actual name of the object?
If you catch them while debugging, of course the program breaks right on the offending creature, but if it happens after the program is in the wild, good luck.
There has to be a way.
I've explored the exceptions returned in these instances and there is just nothing helpful.
No, it's not possible. The exception happens because a reference is null, and references doesn't have names. Variables and class/struct members have names, but it's not certain that the reference is stored in either of those. The reference could for example be created like this:
someObject.GetInstance().DoSomething();
If the GetInstance method returns null, there is a null reference exception when you try to use the reference to call DoSomething. The reference is just a return value from the method, it's not stored in a variable, so there is nothing to get a name from.
If you have debugging information in the compiled assembly, you will get the line number in the stack trace in the exception, but that is as close as you can get.
NullReferenceException is the most evil of all exceptions in an application. It means a possibly-null reference wasn't checked for a null value before it was accessed.
It's evil, because the runtime can't determine what you were expecting to find in the reference, so it can't tell you what precisely failed to be de-referenced.
The stack trace is your only friend in this exception, where it can at least identify which method threw the exception. If your code is neat enough, it should identify a small amount of code to check through.
Additionally, if you're running with a debug build and have the debugging information with the assemblies, you'll even get source line numbers in the stack trace, so you can know exactly what line the method failed on.
The real answer is to prevent this exception from ever being thrown. It's an indicator that some code was poorly written, failing to deal with the scenario where a reference was null.
If you have a method being called where you need to do something with a reference-type argument that needs to be de-referenced at some point, check for null and throw ArgumentNullException, indicating the name of the parameter:
if(parameter == null)
throw new ArgumentNullException("parameter");
If you are performing an operation within a class and a settable property can be set to null, check before de-referencing it and throw an InvalidOperationException indicating the problem:
if(Property == null)
throw new InvalidOperationException("Property cannot be null.");
You should also make sure that all methods you're calling that can return reference types are guaranteed to return a value. For all those that are not, make similar checks for null and handle the case appropriately.
EDIT:
To clarify, I'm not suggesting you perform a check on every reference-type variable before you de-reference it. That would be madness.
It's about understanding where a variable can be assigned null and where it cannot. If you assign a private field in a class to a non-null value in the constructor, and the value is never assigned again, you don't need to check whether the value is null; the design of your class has made sure it never can be.
A well-designed object will restrict the opportunities for null values being assigned and will use guard code where appropriate to throw exceptions when a null value can be present.
This is one of those instances where you really need to attach to the application and step through the general area of the offending code to figure out where that null reference is coming from.
I think currently the best you can get is the line no.
StackTrace:
at test_003.Form1.button1_Click(Object sender, EventArgs e) in C:\Documents and Settings\...\Projects\test_003\test_003\Form1.cs:line 52
If they do something in future about this problem, it would be great.
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.
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.