Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Why do we need to create custom exceptions in .NET?
Specific customs exceptions allow you to segregate different error types for your catch statements. The common construct for exception handling is this:
try
{}
catch (Exception ex)
{}
This catches all exceptions regardless of type. However, if you have custom exceptions, you can have separate handlers for each type:
try
{}
catch (CustomException1 ex1)
{
//handle CustomException1 type errors here
}
catch (CustomException2 ex2)
{
//handle CustomException2 type errors here
}
catch (Exception ex)
{
//handle all other types of exceptions here
}
Ergo, specific exceptions allow you a finer level of control over your exception handling. This benefit is shared not only by custom exceptions, but all other exception types in the .NET system libraries as well.
I did a lengthy blog post on this subject recently:
https://learn.microsoft.com/en-us/archive/blogs/jaredpar/custom-exceptions-when-should-you-create-them
The crux of it comes down to: Only create a custom exception if one of the following are true
You actually expect someone to handle it.
You want to log information about a particular error
So you can also throw them yourself, and then catch them and know exactly what they mean.
Also: if you're building a class library/framework/api, it's often useful to create a BaseException that other exceptions in your code inherit from. Then when your code raises exceptions the programmers who are using it can quickly know the source of the exception.
Because it can make your intentions clear, and you can also track usages using IDE functionality. Say that you have a custom backend system called "FooBar" and you make a "FooBarDownException", you can track usages of this exception to identify any custom logic your application contains because FooBar is down. You can choose to catch this specific type of exception and ignore others, avoiding overloads and conditional logic within exception handlers. It's really just another version of strong typing. It also means you can avoid comments in your code because the exception has an intention revealing name.
I am not sure why "technically" but lets say I have a app/website that uses permissions. If someone does not have the right permission, its kinda stupid to throw a DivideByZero Exception or IOException. Instead I can create my AccessDeniedException which will help me debug later on.
It's the same reason you would create different exit codes for a non-.NET application: to specify different application-specific errors. Like...ConnectionBrokenException or um...UserSmellsBadException...or something.
This way you can know exactly what went wrong and act appropriately. For example, if you try to send some data and the data transport class throws a ConnectionBrokenException, you can pop up a reconnect dialog and try to reconnect. Then the reconnect method would throw a ConnectionTimeoutException if it times out, and you can again act appropriately.
Another reason, when a client talks to interfaces. Since the client is unaware of the implementations of the interface and since they maybe can throw different exceptions, it's good place to create custom exceptions to uniformise the errors thrown.
I wrote about this special case:
http://blog.mikecouturier.com/2010/01/creating-custom-exceptions-in-net-right.html
As Joel wrote: So you can also throw them yourself, and then catch them and know exactly what they mean.
In addition, you can add specific info about the problem in order to let your exception handler act more accurately.
The standard .NET exceptions don't cover everything bad that can go wrong in any application nor are they intended to. Unless your program is very simple, it's likely you will have to create at least a few custom exceptions.
For one thing, Exceptions are implemented in the Library, not in the language--how can they create exceptions in the library? I'm pretty sure you aren't advocating that system libraries should have a different set of rules.
For another, it's actually possible to use an object tree of exceptions. Your inherited exceptions can have special attributes if you like--they can be used for more complicated things than they are. I'm not advocating they be used as a generic data transport mechanism or anything (although they could be), but I could see a case where someone implemented a custom logging solution that required a special attribute on the Exception...
Your custom exceptions could contain a flag indicating special treatment (maybe one saying you should restart the JVM), they could contain information about logging levels, a bunch of stuff.
Anyway, I'm not advocating this stuff, I'm just saying it's possible. The first paragraph is you real answer.
You shouldn't if the built in Exceptions appropriately describes the problem/exception. I wouldn't make my own base classes to create a custom ArgumentException, ArgumentNullException or InvalidOperationException.
You can create your own exceptions, and describe the error at a higher level. however, this usually doesn't help that much in debugging from a consumer class.
If you throw and catch the exception yourself, a custom exception may be in order.
Related
How can I execute some code when my program experiences a fatal error and crashes? For example, something goes wrong and the box pops up that say "TestApp.exe has encountered an error and needs to close." and then I want to write to a file with an error code and say a report of the last few things that were entered into the program. How would I do this in C#??
Depending on the type of application you are writing there are different ways. You may take a look at the following article to see how this could be achieved in a WinForms application.
Generally it's a bad idea to write handlers for Exception, FatalException and two more types, you should be more specific in try.. catch clause. Try explore the Application class, especially its SetUnhandledExceptionMode. You can find a nice example on how to use it here.
It depends on what you are asking here.
Regular exceptions you can get through try/catch.
However if you are running any external dll that may for example get Corrupted state exceptions (CSEs) you need to enable legacyCorruptedStateExceptionsPolicy in your app.config (but dont forget that there is a reason for Microsoft to remove this as default as it was before. You should try to fix this kind of errors not only catch them and forget them)
http://dotnetslackers.com/articles/net/All-about-Corrupted-State-Exceptions-in-NET4.aspx
For logging errors to the file you may use log4net
Any way it should look like:
try
{
// Something potentially dangerous
}
catch (Exception Ex)
{
Logger.Append(Ex.Message);
}
In Java, you explicitly define what exceptions are thrown using the "throws" keyword. That way, anyone calling your method knows what to catch.
Is there something in C#? If not, how do I know what exceptions to catch, or how do I let others know what exceptions to catch?
Also, if I am defining an interface, is there a way to say "methodX() should throw this exception on error"?
There is nothing equivalent in C#: The Trouble with Checked Exceptions
Other than documentation, there is no way to declare an interface to say "methodX() should throw this exception on error".
C#/.net does not have checked Exceptions, they proved to be less useful in large scale systems than first thought. In a lot of projects the time to maintain the check exception specs was a lot greater than the debugging time saved by having them.
Checked Exceptions seem like a good ideal until you have methods that can take delegates or calls into object you pass in. Take a simple case, the Sort() method on a list can’t know what exceptions it will throw, as it does not know what exceptions the Compar() method on the objects being sorted will throw.
So the spec for the exceptions a method may throw must be able to include information on how exceptions are populated from pass in objects and delegates. No one knows how to do this!
However there are tools that you check if you are catching all exceptions – see Exception Hunter by Red Gate. I personally don’t see much value in these tool, however if you like checked exceptions you may find them useful. ==> Looks like Exception Hunter wasn't too useful, so Redgate discontinued Exception Hunter a long while ago:
This feature is not available in C#. You can make proper XML documentation (3 slashes ///) and state what exceptions are being thrown.
This will be picked up by the IntelliSense mechanism and will be visible for the users of the class/method before they use it.
C# does not support this. (Not that I know anyway).
What you can do is use Xml Comments so that while calling you methods this data will be shown by intellisense.
As far as I'm aware there is no throws declaration in C# you can document your method indicating that it throws an exception but no forced error handling.
C# doesn't support checked exceptions. The language designers consider checked exceptions in the way java uses them a bad idea.
Some workarounds
Let me cite this medium article: It's almost 2020 and yet... Checked exceptions are still a thing
Among the many reasons why it's a bad idea, putting the checked exceptions in the contract (interfaces):
makes it impossible to change the implementation of an interface with a different one which throws different exceptions
exposes implementation details
a change of the checked exceptions of an API interface, makes it necessary to change the whole chain of interfaces in the call stack
For example, imagine that you are implementing a repository based on SQL Server, so you expose all kind of SQL Server specific exceptions. Then you want to move it to MySQL or Cosmos BD. Of course:
the implementation can't be changed to a new one that need to throw different exceptions. Also related to this, if you have different implementations of the storage, you can't just change them by configuration, but you need to have different compilations of the code for each storage backend
this is the explanation for 1: as the interface showed the implementation details (SQL Server exceptions) know you can't just change it
if you need to make the change, prepare to change the interface at all levels, since the API that uses the database up to the lates consumer in the call stack chain.
The articles cited above includes pointers to many explanations to discourage the use of checked exceptions, included this by the creator of C#: The trouble with checked exceptions
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.