I am writing an app and I want to load a file based on a path provided by the user. I check the extension of the file and when the extension does not match anything I recognize I want to throw an exception.
I could throw an IOException. But, I figured there could be a more detailed exception derived from that. So I looked at MSDN and found FileLoadException. The name suggests that my error would fit in this category, but.... when I look on MSDN it says: "Represents the error that occurs when a Assembly file is found but cannot be loaded." and "The exception that is thrown when a managed assembly is found but cannot be loaded." That is absolutely not what is the case with my error.
So what is the question then? Well, I wonder if the documentation actually means that the exception is meant to be thrown for this purpose only or that they just mean that they throw that exception in that specific case, but do not really specify when others should throw it.
On the IOException page on MSDN it does advice to use FileLoadException where appropriate:
IOException is the base class for exceptions thrown while accessing information using streams, files and directories.
The Base Class Library includes the following types, each of which is a derived class of IOException:
DirectoryNotFoundException
EndOfStreamException
FileNotFoundException
FileLoadException
PathTooLongException
Where appropriate, use these types instead of IOException.
Summarized: In case of an unknown file extension, should I throw an IOException or a FileLoadException (I do not want to define my own exception).
Thanks in advance.
You should throw IOException, and never throw FileLoadException which is very specific and "technical" (whereas your exception should be "application oriented"). Try to analyze FileLoadException type with Reflector (in mscorlib), you'll see that it's only used for the purpose defined in the msdn. Then imagine one day your code used in a "plugin context", how will react the host program catching a FileLoadException meaning an assembly failed to load properly ...
I wouldn't throw an exception that is documented to be of a very specific use-case and might confuse others.
If you can't define a new exception, stick with IOException.
FileLoadException wouldn't seem to be a good fit, because it's specifically for assemblies.
IOException is suitable, but it feels very generic and wont let callers handle it gracefully, distinguishing it from more general errors.
If you really have to throw an exception here, consider NotSupportedException, which identifies an attempt to perform an operation which your object does not support, in this case loading a file format you don't recognise.
Good practice is to define your own exceptions: derive one from whether Exception or any other more specific Exception subclass.
This will save your time during testing as well as provide you more information with future feedback: you can differ between some exceptions that are not handled in you code and those your own business logic throws based on your specific rules.
Speaking of this case, I advise you create FileExtensionException derived from IOException. This will pretty much ease you code: you won't have to check error message providing separate catch block for new exception type.
It seems a case of just validating the user data.
Why would you want to throw an exception and just not inform the user that he provided an extension that is not recognized by your application?
If you're using the OpenFileDialog you can even use the OpenFileDialog.Filter in order to allow the user to only select a file with an extension supported by your application.
Related
When defining exceptions should you have separate exceptions for every type of error that can occur or a more general exception that can be used for multiple error conditions.
For example lets say that I have a class that processes strings and I want to throw exceptions if a string is not the correct format.
Would I create separate exceptions such as:
StringTooLongException, StringContainsIllegalCharactersException, StringTerminationException
or just create a single exception such as
StringFormatException
and indicate the more specific exception with an error code within the exception?
That depends. Can the receiver of the exception take any useful action depending on the type? Then yes, it would be nice to have different types. If all he can do is show the error message to the user, then different .NET types are not useful and if something has no use, it should not be done.
There are lots of existing "generic" exception types in the .Net framework, e.g., System.IO.IOException covers lots of possible IO errors, and System.Data.SqlClient.SqlException is used for reporting lots of differents types of Sql error, so I would say it is OK to use a more generic exception type, preferably one that already exists (don't reinvent the wheel).
One thing I find very frustrating with C# is when I find some issue and I want to throw a meaningful exception. I find it very difficult to find those exceptions in intellisense. There is no Exception namespace, so I cant list all exceptions via intellisense without digging around looking for the exception.
I am not looking to create my own exceptions, I am only trying to see if there are any other options than googling an exception to find its namespace so I can use it.
For the most part, this is bad practise. There are a small handful of exceptions that you should reuse (InvalidOperation, NullReference, ArgumentException, a few others). But you should not, for example, throw SqlException yourself - because you don't know what the framework might do with it.
Creating your own exception hierarchy adds meaning to your application at times of error. Reusing exceptions that have already-understood meanings leads to confusion - loss of meaning.
You can browse the entire Exception Class Tree in object Browser. Look for System.Exception and then click derived types. not 100% sure if all of them are there but the most of them are there for sure.
System.Exception -> Derived types (also in the root of the System.Excecption tree)
You can find some exceptions in the MSDN, here.
In general, these are the exceptions you'll ever tend to throw, and in many cases, you'll derive your own exceptions from these exceptions. However, a single method throwing too many different exceptions is generally frowned upon.
Also, recall the <exception> xml documentation tag. Using this tag goes a long way towards enlightening users which exceptions your method throws, and when. It's probably more important, in terms of clarity, than throwing exceptions of specific classes.
In our app, we use components developed by other teams. The question was how can I define a nicely way of exception handling than this
try
{
someComponent.DoStuff();
}
catch (Exception ex)
{
textLabel= ex.Message;
}
The component has no custom exception type, maybe a nicely way to do it would be to define a component specific Exception type and wrap this somehow?
I know the question is very basic, but I am interested more in the let's say how it is good to do it. If you call another component with no custom defined exception types, how do you handle any potential exceptions in an elegant way?
Ideally you would have the component development team do this for you - how else do they expect their clients to recognize and handle errors from their component? Scoping the exceptions that a component can raise is a fundamental part of good C# design.
If that's not an option, then implementing your own wrapper on top of the component to taxonomize its failure cases sounds like a good second best, and very noble of you into the bargain.
If the third-party library is poorly documented (they don't specify the exceptions that can be thrown by each method), there are tools available that can Reflect into the code and determine the possible Exceptions that may be thrown. This can get a bit daunting (there are a surprising number of exceptions that can be thrown for any given call), but it's better in principle than catching the general Exception type. Here is one commercial product that performs this type of analysis.
When you catch an error you are able to repackage it and then throw another error, at the most basic level you may just be adding more data - but, from what you've suggested, you could also replace the generic error with a custom error that, whilst it won't overcome the limitations of the response you've got from the component, would give the code further up the call stack the opportunity to respond more appropriately.
So in terms of just adding information in the most basic manner - by throwing a new exception with some additional text whilst still passing the original exception:
catch (Exception ex)
{
throw new Exception("This is more about where the exception occurred", ex);
}
Now, if you want to define your own custom component exception you change the new Exception to new ComponentSpecificException adding data as necessary to the constructor but never forgetting to set the inner exception. Exceptions also have a data collection of key, value pairs into which you can insert more information (by creating the exception, adding the data and then doing the throw).
That's all fairly generic - working forward from there, where you can't necessarily anticipate all the exceptions you have to handle you don't try - you set up logging so that you know when you've got a generic exception i.e. one that hits the final catch - and then over time add exception specific catches above the generic to provide more appropriate responses or, at the very least, package up the error into less general custom exceptions.
Not sure I've explained that very well - but the notion is that as its difficult to anticipate every possible error you want to have a strategy to develop your application in a systematic fashion as you discover new exceptions.
Assuming you want to catch every type of exception, this solution looks fine to me.
Either from your knowledge of using the component, or by using something like Reflector to analyze the compiled component, what possible exceptions can this component throw? Would providing exception handlers for these allow you to provide better feedback to you users?
The only reasonable (much less "elegant") way to handle exceptions is to log them if you can't recover from them.
Then notify the user there was a problem and offer them the chance to try again (if it's an interactive program).
If your application is exclusively for .NET developers, go ahead and show them the exception message (though Exception.ToString is better, since it includes a stack trace). Otherwise, don't display exception messages in your user interface - that's a security hole and will only confuse your users.
If I need to throw an exception from within my application which of the built-in .NET exception classes can I use? Are they all fair game? When should I derive my own?
See Creating and Throwing Exceptions.
On throwing built-in exceptions, it says:
Do not throw System.Exception, System.SystemException, System.NullReferenceException, or System.IndexOutOfRangeException intentionally from your own source code.
and
Do Not Throw General Exceptions
If you throw a general exception type, such as Exception or SystemException in a library or framework, it forces consumers to catch all exceptions, including unknown exceptions that they do not know how to handle.
Instead, either throw a more derived type that already exists in the framework, or create your own type that derives from Exception."
This blog entry also has some useful guidelines.
Also, FxCop code analysis defines a list of "do not raise exceptions" as described here. It recommends:
The following exception types are too general to provide sufficient information to the user:
System.Exception
System.ApplicationException
System.SystemException
The following exception types are reserved and should be thrown only by the common language runtime:
System.ExecutionEngineException
System.IndexOutOfRangeException
System.NullReferenceException
System.OutOfMemoryException
So in theory you can raise any other framework exception type, providing you clearly understand the intent of the exception as described by Microsoft (see MSDN documentation).
Note, these are "guidelines" and as some others have said, there is debate around System.IndexOutOfRangeException (ie many developers throw this exception).
On the subject of System.Exception and System.ApplicationException: The latter was meant to be used as the base class of all custom exceptions. However, this hasn't been enforced consistently from the beginning. Consequently, there's a controversy whether this class should be used at all rather than using System.Exception as the base class for all exceptions.
Whichever way you decide, never throw an instance of these two classes directly. It's actually a pity that they aren't abstact. For what it's worth, always try using the most specific exception possible. If there is none to meet your requirement, feel free to create your own. In this case, however, make sure that your exception has a benefit over existing exceptions. In particular, it should convey its meaning perfectly and provide all the information necessary to handle the situation in a meaningful manner.
Avoid to create stub exceptions that don't do anything meaningful. In the same vein, avoid creating huge exception class hierarchies, they're rarely useful (although I can imagine a situation or two where I would use them … a parser being one of them).
I use the ArgumentException (and its “friends”) regularly.
NotSupportedException and NotImplementedException are also common.
My advice would be to focus on two things:
Scenarios
User expectations
In otherwords, I would sit down and identify:
Under what scenarios do you want to throw exceptions.
In those scenarios, what would the users of your API expect
The answer to #1 is, of course, application specific. The answer to #2 is "what ever similar code they are already familiar with does".
The behavior that comes out of this is:
Under the scenarios that arise in your programs that also arrive inside the
framework, such as arguments being null, out of range, being invalid, methods not
being implemented, or just not supported, then you should use the same exceptions the
framework uses. The people using your APIs are going to expect that they behave that
way (because that's how everything else behaves), and so will be better able to use
your api from the "get go".
For new scenarios that don't exist in the framework, you should go ahead and invent
your own exception classes. I would say that you should prefer Exception as your base
class unless their is some other base exception that provides services you need.
Generally speaking I don't think something like "ApplicationException" will help you
much. When you start defining your own exceptions there are a few things you should
keep in mind though:
a. The primary purpose of an exception is for human communication. They convey
information about something that happened that shouldn't have. They should provide
enough information to identify the cause of a problem and to figure out how to
resolve it.
b. Internal consistency is extremely important. Making your app behave as universally
as possible under similar circumstances will make you API's users more productive.
As far as there being hard and fast rules about what you should and should not do... I wouldn't worry about that stuff. Instead I would just focus on identifying scenarios, finding the existing exception that fits those scenarios, and then carefully desining your own if an existing one doesn't exist.
You can create and throw pretty much any of them, but you generally shouldn't. As an example, the various argument validation exceptions (ArgumentException, ArgumentNullException, ArgumentOutOfRangeException, etc) are suitable for use in application code, but AccessViolationException isn't. ApplicationException is provided as a suitable base class for any custom exception classes you may require.
See this MSDN article for a list of best practices - it refers to handling exceptions, but also contains good advice on creating them...
I have an application which tries to load some expected registry settings within its constructor.
What is the most appropriate .NET Exception from the BCL to throw if these (essential, non-defaultable) registry settings cannot be loaded?
For example:
RegistryKey registryKey = Registry.LocalMachine.OpenSubkey("HKLM\Foo\Bar\Baz");
// registryKey might be null!
if (registryKey == null)
{
// What exception to throw?
throw new ???Exception("Could not load settings from HKLM\foo\bar\baz.");
}
Why not create your custom exception?
public class KeyNotFoundException : RegistryException
{
public KeyNotFoundException(string message)
: base(message) { }
}
public class RegistryException : Exception
{
public RegistryException(string message)
: base(message) { }
}
....
if (registryKey == null)
{
throw new KeyNotFoundException("Could not load settings from HKLM\foo\bar\baz.");
}
Also, instead of inheriting from Exception you could inherit from ApplicationException. This depends on the kind of failure you want your application to have in this situation.
actually, I wouldn't throw an exception here. I would have a default value, and then create the key using that default value.
If you MUST have a user-defined value, I'd use the ArgumentException (as that's fundamentally what you're missing, an argument for your constructor--where you store it is irrelevant to the type of exception you're trying to generate).
I'd go with ArgumentException or ArgumentOutOfRangeException..
throw new ArgumentException("Could not find registry key: " + theKey);
Quoting MSDN:
The exception that is thrown when one
of the arguments provided to a method
is not valid.
...
IMO writing a proper exception message is more important.
It depends on why it failed. If it's a permissions issue, the I'd go with System.UnauthorizedAccess exception:
The exception that is thrown when the operating system denies access because of an I/O error or a specific type of security error.
I don't know if it matches the "specific type", but it is a security error, and access wasn't authorized.
On the other hand, if the item just doesn't exist then I'd thrown a FileNotFound exception. Of course, a registry key isn't a file, but FileNotFound is pretty well understood.
Since this entry is as you put it an essential value, what is the impacts to your application if this value cannot be obtained? Do you need to hault operations or do you simply need to notify the application.
Also, there are a number of reasons that the value could be null
User doesn't have permission to read the key
The key doesn't exist
Does this impact the action you take when working with the application?
I think that these types of scenarios play into what exception to throw. Personally I would never throw just Exception, as it really is a "no-no" from a standard design practice.
If it is due to a user not having permissions, AND then not having this permission might cause future problems I would vote for an UnauthroizedAccess exception.
If the issue is not a critical issue, but you really need to know that the key isn't there I would strongly recommend the "KeyNotFoundException" implementation mentioned elsehwere.
When throwing an exception you want to make sure that the exception being thrown is descriptive and provides all needed information, thus why I think it depends on the root cause as well as the overall impacts to the application.
To quote MSDN's "Design Guidelines for Developing Class Libraries"
ApplicationException
If you are designing an application
that needs to create its own
exceptions, you are advised to derive
custom exceptions from the Exception
class. It was originally thought that
custom exceptions should derive from
the ApplicationException class;
however in practice this has not been
found to add significant value. For
more information, see Best Practices
for Handling Exceptions.
I think that the best approach is to take a step back. If there is not a clear cut exception that describes what is happening, it takes only minutes to define one. Try to avoid repurposing exceptions because it "is close enough".
My recommendation is that you should create a base exception class which inherits from either Exception or ApplicationException. This will allow for you to easily identify, from your stack trace, whether the exception is a custom exception that you defined or whether it originated somewhere else. All of your custom exceptions should inherit from the base exception that you create.
Note: I am not going to recommend the use of either Exception or ApplicationException. There is enough debate in the community vs. Microsoft's documentation over which should be used and for what purpose. On a personal level, I choose Exception as my base exception.
If there is not a clearly predefined exception that matches your intent, going forward, derive a custom exception from your base exception. It definitely helps in tracing down the origin of a problem, makes them easier to handle (imagine that an existing framework exception was thrown in the block of code, but by the framework or another method), and just plain makes sense.
Keep in mind, you can have multiple exception hierarchies to group like exceptions together. For example, I can have MyBaseException which inherits either ApplicationException or Exception. I then can have a more generalized MyRegsitryException which inherits from MyBaseException. Then I can have specific exceptions, such as MyRegistryKeyNotFoundException or MyRegistryKeyPermissionException.
This allows you to catch a grouped exception on a higher level and reduce the number of catches that you might have that contain redundant handling mechanism. Combine this with isolating the scope of the exceptions to specific namespaces that would use them, and you have the start of a very clean exception handling scheme.
I would probably throw an ApplicationException since this is specifically related to your application. Alternatively, you could throw a ConfigurationErrorsException, though this is usually associated with an error parsing an application configuration file, not reading the configuration from the registry.
The other potential exceptions that come to mind are ArgumentException or ArgumentNullException, but these have a connotation of being related to parameters that are passed into the method and are not, therefore, appropriate to my mind. It could easily lead someone using/modifying your code astray when trying to determine why it is not working.
In any case, a good, descriptive error message is probably the most effective way of communicating what the problem is.
EDIT: Note that throwing an exception on a null value doesn't mask any exceptions that would occur when attempting to read the registry value. I believe that any SecurityException that gets thrown when you attempt to read the value without sufficient privileges will still occur as long as you don't wrap it in a try/catch block.
I think just Exception itself could do the job. If your message is descriptive enough, then it's all good. If you really want to be precise about it, then I'd agree with petr k. Just roll your own.