How to handle Exception and display appropriate message using C#? - c#

I am working in MVC3 Dot Net project Using EF.
We are catching all the Exceptions in an object of Exception (i.e ex)
From this how can I get (or filter) SQlExceptions and I like to show the meaningful message.
facing problem :
I am not getting System.Data.UpdateException class

loop through exception/inner excetion and check if(ex is SQlException) { }
Maybe you missed adding reference to System.Data.Entity so you dont see System.Data.UpdateException class

You shouldn't be catching Exception first (or at all unless you are specifically doing something with all exceptions)
If you want only UpdateExceptions, then you should only catch that exception.
This catch should be above any other handlings that are more generic, for example
try
{
}
catch(System.Data.UpdateException ex)
{
}
catch(Exception ex) //optionally
{
///less generic handling
}
Also consider for general logging ELMAH
http://code.google.com/p/elmah/

Related

How to manage specific and generic exceptions

What happens here if the OracleException here is not what I am looking for? Do I need to throw? Also catching a generic exception here is that the right thing to do?
try
{
does some code
}
catch (OracleException ex)
{
if (ex.Number == 20001)
{
throw new ValidationException("Unable blah blah blah");
}
throw;
}
catch (Exception ex)
{
// Log it
TraceHelper.WriteLine("Exception updating tblah + Environment.NewLine + ex.StackTrace, MessageCategory.Error);
throw;
}
A really good thing to do is to realize when you have a bug in your code. How do you do that? Normally crashing or putting a global exception handler that traps Exceptions and informs the developer in some way.
Catching a generic exception and not throwing it goes against the previous statement so it is advised to not do it.
It is usually accepted as a good practice to fail fast (here a description)
At last but not lease you normally do not want to catch an exception that you don't know how to recover from. What will you do in your application if you have a bug and you have an ArgumentNullException? There is nothing you can do in your code to recover from this situation, you must fail, inform de user and the developer and end the application.
This looks like you want to only catch the OracleException based on some condition of that exception. The good news is, with C# 6.0 you can add a when clause to add that condition:
catch (OracleException ex) when (ex.Number == 20001)
{
throw new ValidationException("Unable blah blah blah");
}
This means that if ex.Number isn't 20001, the exception thrown will check the next catch clause you have, in this case, it will fall into your generic catch.
Whether or not the generic catch should be there is up to debate, as a general rule of thumb, you shouldn't have generic exception handling. If you don't know why the code is throwing the exception, how can you expect to handle it successfully?

Find out specific Exception

Apologies for the lack of information...
Is there a way to find out what is the specific Exception that is causing a call to throw the Exception?
Currently, I am catching all the Exceptions by doing catch(Exception e) but I know this is not good practices at all.
Is there a way to know from the Exception what is the specific one that caused the issue so I can be more granular?
You can get more information for the particular exception using different methods on it. Here I'm using the System.Diagnostics.Debug class to print in Visual Studio's output console. In your catch block:
using System.Diagnostics;
try
{
// do stuff
}
catch (Exception e)
{
Debug.WriteLine(e.GetType()); // Displays the type of exception
Debug.WriteLine(e.Message()); // Displays the exception message
}
You can see more here: Exception methods &
Exception properties
Option 1 - Documentation
Read the documentation of the method you are calling, if it is a Framework Class type (like SqlConnection.Open) the thrown exceptions are well documented.
Option 2 - Discover them at Run Time
If its a 3rd party library and documentation is limited then check the Exception at runtime using exception.GetType() and then add known exceptions you want to handle as catch blocks.
Personally I prefer to not add catch blocks at all where I am not sure if an Exception will materialize or not. If/When it does the debugger will break (if it is set to break) or you have a global catch all that logs and rethrows. Then you get the type and update your code accordingly. Where you add such a global Exception logger depends on the type of application you are developing. If you go the route of a global logger do take note that you 1) rethrow the Exception so the app breaks at runtime and not swallow it and 2) rethrow using throw; syntax (not throw ex;).
You can catch different types of exceptions. With this solution you are able to handle the different types easily.
try
{
//Try something
}
catch (StackOverflowException soe)
{
//Handle StackOverFlowException
}
catch (FormatException fe)
{
//Handle FormatException
}
//... Other exceptions
If you want to make it more specific for logging errors, try something like:
e.GetType()
Or, if you need some more information like the StackTrace or message:
e.ToString()
If you only want to catch a specific type of exception, you need to do something like:
try {
// someCode
} catch (SpecificExceptionType e) {
// someCode (e.g. Console.WriteLine(e.ToString()); )
}
catch (AnotherSpecificExceptionType e) {
// someCode (e.g. Console.WriteLine(e.ToString()); )
}

How to return an exception thrown in one project to another?

is there any way to catch and return an exception thrown from one project to another?
For example, i'm keeping codes in different projects . Say A and B. If A is the engine part and B is the UI part, then an exception occurred in the engine should be caught in UI as well.Please help.
The only reason you'd want to catch the exception in your engine code is if you thought you could handle it, or you needed to do some logging or something like that. There isn't much (any) benefit in catching simply to rethrow. However, assuming you have a valid reason, then in your UI code you can have
try
{
engine.Start();
}
catch (SpecificException se)
{
// Do stuff with specific exception
}
catch (Exception ex)
{
// Show the user something unexpected happened
}
In your Engine code, you can have;
public void Start()
{
try
{
if (this.HasNoOil)
{
throw new SpecificException("Can't go without oil. We'll do some damage");
}
// Other stuff
}
catch (Exception ex)
{
// Log details of exception and throw it up the stack
throw;
}
}
If you want to catch exceptions at the UI level you can not catch them at your engine level.
For the running application there is no difference in which assembly (every project creates an assembly) the exception was thrown.
If you really have to catch and re-throw the exception at your engine level re-throw correctly
catch(Exception ex)
{
// whatever logic
throw;
}
or wrap it
catch(Exception ex)
{
// whatever logic
throw new YourEngineException("Some Message", ex);
}
If you just want to log it, don't do it, if it does not cross process boundaries.
Catch, log, re-throw is an anti pattern in my opinion. It just creates a bazillion log entries, catching at the highest possible level should be enough if you don't destroy the stack trace.
Use wrapping if you can provide extra information to the exception. For Example if you have one method which loads data, changes and saves it you could wrap the exception and add "Error '{0}' when saving" or something else. However don't forget to include the originating exception as inner exception.
In my view it is not possible, until unless these two application share same App domain. To make them part of single app domain you need do remoting or wcF kind of stuff, where you can share the objects between two projects.

WCF/C# Unable to catch EndpointNotFoundException

I have created a WCF service and client and it all works until it comes to catching errors. Specifically I am trying to catch the EndpointNotFoundException for when the server happens not to be there for whatever reason. I have tried a simple try/catch block to catch the specific error and the communication exception it derives from, and I've tried catching just Exception. None of these succeed in catching the exception, however I do get
A first chance exception of type
'System.ServiceModel.EndpointNotFoundException'
occurred in System.ServiceModel.dll
in the output window when the client tries to open the service. Any ideas as to what I'm doing wrong?
I was able to replicate your issue and got interested (since I needed the same). I even researched a way to handle \ catch first chance exceptions but unfortunately it is not possible (for managed code) for .net framework 3.5 and below.
On my case I always get a System.ServiceModel.CommunicationObjectFaultedException whenever something gets wrong on the service or whenever I access a down service. It turns out that c#'s using statement is the cause since behind the scene, the using statement always closes the service client instance even if an exception was already encountered (it doesn't jump to catch statement directly).
What happens is that the original exception System.ServiceModel.EndpointNotFoundException will be replaced by the new exception System.ServiceModel.CommunicationObjectFaultedException whenever the using tries to close the service client instance.
The solution i've made is to not use the using statement so that whenever an exception is encountered inside the try block it will instantly throw the exception to the catch blocks.
Try to code something like:
DashboardService.DashboardServiceClient svc = new Dashboard_WPF_Test.DashboardService.DashboardServiceClient();
try
{
svc.GetChart(0);
}
catch (System.ServiceModel.EndpointNotFoundException ex)
{
//handle endpoint not found exception here
}
catch (Exception ex)
{
//general exception handler
}
finally
{
if (!svc.State.Equals(System.ServiceModel.CommunicationState.Faulted) && svc.State.Equals(System.ServiceModel.CommunicationState.Opened))
svc.Close();
}
Instead of:
try
{
using (DashboardService.DashboardServiceClient svc = new Dashboard_WPF_Test.DashboardService.DashboardServiceClient())
{
svc.GetChart(0);
}
}
catch (System.ServiceModel.EndpointNotFoundException ex)
{
//handle endpoint not found exception here (I was never able to catch this type of exception using the using statement block)
}
catch (Exception ex)
{
//general exception handler
}
And you'll be able to catch the right exception then.
Take a look at this post for details on this possible solution. The code shows use of a generate proxy but is valid on ChannelFactory and others as well.
Typical here-be-dragons pattern
using (WCFServiceClient c = new WCFServiceClient())
{
try
{
c.HelloWorld();
}
catch (Exception ex)
{
// You don't know it yet but your mellow has just been harshed.
// If you handle this exception and fall through you will still be cheerfully greeted with
// an unhandled CommunicationObjectFaultedException when 'using' tries to .Close() the client.
// If you throw or re-throw from here you will never see that exception, it is gone forever.
// buh bye.
// All you will get is an unhandled CommunicationObjectFaultedException
}
} // <-- here is where the CommunicationObjectFaultedException is thrown
Proper pattern:
using (WCFServiceClient client = new WCFServiceClient())
{
try
{
client.ThrowException();
}
catch (Exception ex)
{
// acknowledge the Faulted state and allow transition to Closed
client.Abort();
// handle the exception or rethrow, makes no nevermind to me, my
// yob is done ;-D
}
}
Or, as expressed in your question without a using statement,
WCFServiceClient c = new WCFServiceClient();
try
{
c.HelloWorld();
}
catch
{
// acknowledge the Faulted state and allow transition to Closed
c.Abort();
// handle or throw
throw;
}
finally
{
c.Close();
}
This may be a reporting issue for the debugger, rather than not actually catching the exception. this post gives some tips on resolving it, if that is the case... Why is .NET exception not caught by try/catch block?
What is a First Chance Exception?
First chance exception messages most
often do not mean there is a problem
in the code. For applications /
components which handle exceptions
gracefully, first chance exception
messages let the developer know that
an exceptional situation was
encountered and was handled.
Place a try catch block in the CompletedMethod.
An Example:
...
geocodeService.ReverseGeocodeCompleted += ReverseGeocodeCompleted(se, ev);
geocodeService.ReverseGeocodeAsync(reverseGeocodeRequest);
}
private void ReverseGeocodeCompleted(object sender, ReverseGeocodeCompletedEventArgs e)
{
try
{
// something went wrong ...
var address = e.Result.Results[0].Address;
}
catch (Exception)
{ // Catch Exception
Debug.WriteLine("NO INTERNET CONNECTION");
}

Catch Block Choices

I am reading C# article.It suggests that
At the end of the catch block, you have three choices:
• Re-throw the same exception, notifying code higher up in the call stack of the
exception.
• Throw a different exception, giving richer exception information to code higher up in
the call stack.
• Let the thread fall out of the bottom of the catch block.
I am unable to understand the points.It would be a great help, if you clarify it by giving simple example.
Thanks in advance.
Update :
When i need to handle rethrown exception ,do i need to have nested try .. catch blocks like
try
{
try
{
}
catch(InvalidOperationException exp)
{
throw;
}
}
catch(Exception ex)
{
// handle the exception thrown by inner catch block
// (in this case the "throw" clause inside the inner "catch")
}
}
Well, here are those different options in code:
Option 1: Rethrow
try
{
// Something
}
catch (IOException e)
{
// Do some logging first
throw;
}
Option 2: Throw a different exception
try
{
// Something
}
catch (IOException e)
{
// Do some logging first
throw new SorryDaveICantDoThatException("Oops", e);
}
Option 3: Let the thread fall out of the bottom
try
{
// Something
}
catch (IOException e)
{
// Possibly do some logging, and handle the problem.
// No need to throw, I've handled it
}
EDIT: To answer the extra question, yes - if you need to handle a rethrown exception, that needs to be handled in an outer scope, exactly as shown in the question. That's very rarely a good idea though. Indeed, catch blocks should relatively rare in the first place, and nested ones even more so.
These are the choices. Difference between 1 and 2 is that if an exception is thrown and you want to debug to the position is it thrown, you will get there with option 1
(all the way down in the try block at the specific object). With option 2 you will and up only at that line (throw new Exception2())
3 is when you want to ignore the exception and just continue
//1
catch (Exception ex)
{
throw;
}
//2
catch (Exception ex)
{
throw new Exception2();
}
//3
catch (Exception ex)
{
}
return something;
In most production systems the last thing you want is a truly unhandled exception. This is why you typically try and catch statements.
You might be wondering why you would want to throw an error you've caught, and here are a few real world examples.
You've caught an exception in a WCF Application, logged the exception, then thrown a faultException instead to be returned to the WCF client. In the same way you might have a traditional asmx, caught an exception, then thrown a SOAP exception back to the client. Point is certain exceptions need to abide by certain rules: a standard .net exception would not be digested well by a WCF client for example.
You've caught an exception somewhere deep inside your code, logged the exception and possibly even taken some action. But higher up in your code you have another routine that is also waiting for exceptions, at this point higher up, an exception could easily change the business workflow. By catching the exception lower down, the code higher up is not aware of any exception, so you need to throw the exception back out to be caught higher up, so that the code you wrote up there can adjust the workflow. Ofc none of this happens by magic, it all has to be coded, and differant programmers use differant techniques.
You might also want to catch an exception around just 1 or a few statements, for example getting a configuration value from an XML file, if something goes wrong, .net might just return object reference not set. You might catch this, then rethrow the exception as "Configuration Value : Customer Name not provided".
Hope this helps.
rethrow the same exception:
try
{
// do something that raises an exception
}
catch (SomeException ex)
{
// do something with ex
throw;
}
throw a different exception
try
{
// do something that raises an exception
}
catch (SomeException ex)
{
// do something with ex
throw new SomeOtherException(ex); // NOTE: please keep ex as an inner exception
}
let the thread fall out:
try
{
// do something that raises an exception
}
catch (SomeException ex)
{
// do something with ex
}
// the code will finish handling the exception and continue on here
1) Re-throw
try
{
...
}
catch (Exception e)
{
...
throw;
}
2) Throw a new exception
try
{
...
}
catch (Exception e)
{
...
throw new NewException("new exception", e);
}
3) Fall out
try
{
...
}
catch (Exception e)
{
...
}
You could also return in the catch block, so there is that 4th option. Return false, return null, etc... (even return a default value.)
Letting the catch block fall through implies that you have successfully dealt with the Exception that was raised in your try block. If you haven't, better rethrow, or fail in some other way.
this isn't c# specific, it's true of any programming language (call them exceptions, call them errors, call them whatever you want).
So, the answer to you question is that this is a basic premise of all programming and you must determine the correct action to take in your code, given the error, the circumstance and the requirements.
Taylor,
As you are learning about Exception handling I would like to add my 2 cents. Exception throwing is very expensive ( expensive being memory hogging of course ) so in this case you should consider assigning the error message to a string and carry it forward through the application to the log or something.
for example:
string errorMessage = string.empty;
try
{
...
}
catch(Exception e)
{
errorMessage = e.Message + e.StackTrace;;
}
This way you can carry this string anyway. This string can be a global property and can be emailed or logged in text file.
I think that there is something to add to the great answers we've already got here.
It may be part of your overall architectural design (or not) but what I've always observed is that you typically only catch where you can add value (or recover from the error) - in other words, not to try...catch...re-throw multiple times for a single operation.
You should normally plan a consistent pattern or design for how you handle exceptions as part of your overall design. You should always plan to handle exceptions in any case, unhandled exceptions are ugly!

Categories