Whats wrong with this re-throwing exception? - c#

I'm using wcf Service to insert data to DB and my service crashes saying exception un-handled. I'm trying to pass on exception from one WCF service method to other WCF method and from there throwing exception to client.
Here is My code:
Data Inserting Method of WCF Service: method to insert data to DB
public int insertStatements(SqlCommand cmd)
{
Try
{
//insert data to the db
}
catch(SqlException ex)
{
if (ex.Number == 2627) // if unique key constraint error
{
throw new FaultException( "error reason", new FaultCode("Error Code: ");
}
else
{
throw new FaultException("DB error: ", new FaultCode("Error Code: " +);
}
}
catch (FaultException ex)
{
throw new FaultException("Unknown Error",new FaultCode("Unknown Error"));
}
}
WCF Insert location method, which is service exposed method(Public)
public int insertLocation (string name)
{
try
{
// this method communicates with client
dataconnection.insertStatements(cmd);
}
catch
{
throw; // Here i'm getting error
}
}
in my client: winform Application
try
{
AreaDataServicesClient DataObject = new AreaDataServicesClient("BasicHttpBinding_IAreaDataServices");
int rowsAffected = DataObject.InsertProvince(ProvinceObject.AreaName, ProvinceObject.AreaKm);
return rowsAffected;
}
catch(FaultException ex)
{
messagebox.show("erro occured");
}
This is the Error i get:
"An exception of type 'System.ServiceModel.FaultException' occurred in EMSDataServices.dll but was not handled in user code"
Why service method does not pass exception to the client.

i found it. There was nothing wrong with the code. i was running the services on debug mode and in exception setting 'break at this point if user code is unhandled' was checked,so it was stopping the service to perform further action and client was crashing due to no response from service.
i unchecked it and it works as expected.

#Mohsin, catch (FaultException ex) in insertStatements is useless. It will never catch your exception. because you are throwing the exception outside the method. You should handle the exception somewhere which is re-thrown. That you can do it in the insertLocation method. See the bellow modified code.
public int insertLocation(string name)
{
try
{
dataconnection.insertStatements(cmd);
}
catch (FaultException ex)
{
// you should handle the exception here. Do not retrow here too. Otherwise you may need to handle somewhere else again.
}
}
public int insertStatements(SqlCommand cmd)
{
try
{
//insert data to the db
}
catch (SqlException ex)
{
if (ex.Number == 2627) // if unique key constraint error
{
throw new FaultException("error reason", new FaultCode("Error Code: ");
}
else
{
throw new FaultException("DB error: ", new FaultCode("Error Code: ");
}
}
}

The line marked ///Here i'm getting the error is a throw statement. That's exactly what it's supposed to do. It's taking the exception which has been caught (because it's in a try) and making it unhandled again, as if it had never been caught.
That's what you might do if you wanted to log or inspect the exception and then let it bubble up. In this case it's exactly the same as removing the entire try/catch.
This:
public int insertLocation (string name)
{
try
{
dataconnection.insertStatements(cmd);
}
catch
{
throw; // Here i'm getting error
}
}
is the same as this:
public int insertLocation (string name)
{
dataconnection.insertStatements(cmd);
}

Related

How to resume second method after first method throws an exception C#

While looking on C# try catch tutorial, I got following question. My sample code as follows,
Inside mainMethod() , I need to call three separate methods. Inside testMethodOne(), I need to handle exception as. If testMethodOne() throws exception, without executing testMethodTwo(dt), mainMethod() throwing exception. I need to call testMethodTwo(dt); and testMethodThreee(dt); if testMethodOne() throws exception, how can I do it.
public void MainMethod(data dt){
try{
testMethodOne(dt);
testMethodTwo(dt);
testMethodThreee(dt);
}catch(Exception ex){
throw ex;
}
}
public void testMethodOne(dt){
try
{
// Block of code to try
}
catch (Exception e)
{
// Block of code to handle errors
}
}
I understood your question as follows (but I might be wrong, your questions is not very clear):
Even if one of your testMethods throws an exception, you still want to continue in the normal program flow with the other methods. If at least one of the method failed, mainMethod could then report this as AggregateException.
public void MainMethod(data dt)
{
var exceptions = new List<Exception>();
try
{
testMethodOne(dt);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
try
{
testMethodTwo(dt);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
try
{
testMethodThreee(dt);
}
catch (Exception ex)
{
exceptions.Add(ex);
}
if (exceptions.Count > 0)
{
throw new AggregateException(exceptions);
}
}
It seems as if you want exceptions to alter the flow of your main method without breaking everything. One easy method is to make each 'testmethod' return a boolean.
public bool testMethodOne(dt){
try
{
// Block of code to try
return true;
}
catch (Exception e)
{
// Block of code to handle errors
return false;
}
}
Then in your main code you can go
if(!testMethodOne(dt))
if(!testMethodTwo(dt))
if(!testMethodThree(dt))
//log that all methods failed
The above snippet would try each method until it finds one that succeeds. If that's not the behaviour you are looking for can you reword your question to make it clearer? If you want the opposite to happen just get rid of the ! and it will go until one fails. Alternatively you could put a throw in your catch statement in each of the testMethods, and that would stop execution once one is reached as well.

Rethrowing Exception from Child method to Root method

I have a method calling combo as below:
Void MainMethod()
{
try
{
for(i = 0; i < 10; i++)
{
Childmethod_1();
}
}
catch(Exception ex)
{
throw ex;
}
}
Childmethod_1()
{
try
{
Childmethod_2();
}
catch(Exception ex)
{
Report(ex);
}
}
Childmethod_2()
{
try
{
[Block of Code]
}
catch(Exception ex)
{
throw ex;
}
}
Report(ex) in the Childmethod_1() is used to log the exception details into Database. If there is an exception occures in the Childmethod_2() whenever 'i' in the MainMethod(): For Loop is 4, will this exception block the rest 6 from the action?
The throw from Childmethod_2 will be caught by the catch from Childmethod_1 and logged to DB too. That catch block does not throw it again, so the exception will not be seen in your main loop, which will not be interrupted.
By the way,
catch(ex)
{
throw ex;
}
isn't only bad practice, it's completely useless. Why not just let the exception happen? Furthermore, the exception sent will not be complete, you'll lose the stack trace. If you really wish to do so, just throw like that:
catch(ex)
{
throw;
}
The answer to your question depends on implementation of Report(ex) method. If it doesn't rethrow the exception, but only stored exception data into the DB, then all iterations of your loop will be executed regardless exceptions occurred. In this case you can simplify your code (look below). Note that in this case you should make sure that Report(ex) method can't throw other exceptions (for example accessing to the database).
void MainMethod()
{
for(i = 0; i < 10; i++)
{
Childmethod_1();
}
}
Childmethod_1()
{
try
{
[Block of Code]
}
catch(Exception ex)
{
Report(ex);
}
}
On the other hand if Report(ex) rethrows exception after storing data into the DB, then the exception will be caught in the catch block of MainMethod and other iterations will not be executed. In this case you can't omit the try-catch block in MainMethod. However ChildMethod_2 is still redundant.

Object not set to a reference

This issue drives me insane, as I can't see what's causing it. The behavior is unexpected and I just can't see how it can occur. When I execute my plugin using the code below, I get the error message "bada boom". Just as expected.
public void Execute(IPluginExecutionContext context)
{
throw new Exception("bada boom");
try
{
throw new Exception("bada bing");
...
} catch (Exception) { }
...
}
However, when I comment out the first throw, I don't get to see "bada bing". Instead, I get "object not set to a reference"! What the duck?! (Typo intended.)
public void Execute(IPluginExecutionContext context)
{
//throw new Exception("bada boom");
try
{
throw new Exception("bada bing");
...
} catch (Exception) { }
...
}
Here's graphics for the issue.
In your first example the exception is handled at the caller level and up till a catch block is found. In the second example the exception is handled in the mandatory catch or finally block associated with the try of the Execute method.
So in the code inside that catch or finally block you have a null reference exception
void Main()
{
try
{
Execute();
}
catch(Exception x)
{
Console.WriteLine("In main: " + x.Message);
}
}
public void Execute()
{
// Goes to the catch block in main
//throw new Exception("bada boom");
try
{
// Goes to the catch block associated with this try
throw new Exception("bada bing");
}
catch(Exception x)
{
// Uncomment this to see the null reference exception in main
// Console.WriteLine("In Execute: " + x.InnerException.Message);
Console.WriteLine("In Execute:" + x.Message);
}
}
Well, of course, when I say mandatory I want to say that you cant write
try
{
....
}
without a catch or a finally clause following the try. And you can write a catch or finally block without code, but you can't omit one of the two keywords and its block

How to determine if an exception is of a particular type

I have a piece of try catch code:
try
{
...
}
catch(Exception ex)
{
ModelState.AddModelError(
"duplicateInvoiceNumberOrganisation", "The combination of organisation and invoice number must be unique");
}
For this piece of code I'm trying to insert a record into a database: The dba has set it up so that the database checks for duplicates and returns an error if there are duplicates. Currently, as you can see, I'm adding the same error to the model no matter what error occurred. I want it changed so this error is only added to the model if it was caused by the duplicate error set up by the dba.
Below is the error I want to catch. Note it's in the inner exception. Can anyone tell me how to specifically catch this one?
before your current catch add the following:
catch(DbUpdateException ex)
{
if(ex.InnerException is UpdateException)
{
// do what you want with ex.InnerException...
}
}
From C# 6, you can do the following:
catch(DbUpdateException ex) when (ex.InnerException is UpdateException)
{
// do what you want with ex.InnerException...
}
Replace System.Threading.ThreadAbortException with your exception.
try
{
//assume ThreadAbortException occurs here
}
catch (Exception ex)
{
if (ex.GetType().IsAssignableFrom(typeof(System.Threading.ThreadAbortException)))
{
//what you want to do when ThreadAbortException occurs
}
else
{
//do when other exceptions occur
}
}
Not enough rep to comment. In response to #conterio question (in #Davide Piras answer):
is there a catch "when not" syntax?
There is.
catch (Exception e) when (!(e is ArgumentException)) { }
To get name of the exception you can use
catch (Exception exc){
if (exc.GetType().FullName == "Your_Exception")
{
// The same can be user for InnerExceptions
// exc.InnerException.GetType().FullName
}
}
You can take a look at the SQLException class -- and check for the contents of the exception's message if it contains what you now see in your inner exception..Something like this:
try
{
//your code here
}
catch (SQLException ex)
{
if (ex.Message.Contains("Cannot insert duplicate key in obj...."))
{
//your code here
}
}

C# Catch re-throw/propagation for a specific exception type

I am trying to propagate to my UI the GatewayConnectionFailedException as you can see. I want this code to catch everything except that exception which I want the presentation layer to catch to notify the user that the database was the problem so he can go and fix it. My problem is that when I throw it the first time then I get GatewayConnectionFailedException not handled by user code on the GatewayException catch clause.
Its also important to note the the GatewayConnectionFailedException extends GatewayException which extends Exception. Is there something I am missing or will I have to move all the catch to the presentation layer ?
try
{
something();
}
catch (GatewayConnectionFailedException gcfe)
{
throw;
}
catch (GatewayException ge)
{
if (ge.GetType() == typeof(GatewayConnectionFailedException))
throw;
string errMsg = "Records could not be retrieved due to a data gateway error. " + GetTypeInfo();
_logger.Error(errMsg + "\r\n{0}", ge);
}
catch (Exception e)
{
if (e.GetType() == typeof(GatewayConnectionFailedException))
throw;
string errMsg = "Records could not be retrieved due to an unexpected error. " + GetTypeInfo();
_logger.Error(errMsg + "\r\n{0}", e);
}
Stupid question... is your UI code try-catching in it's call to this layer? Something has to handle that second throw...
In a nutshell, it sounds like you're trying to do this:
using System;
namespace ConsoleApplication1
{
class ExceptionA : Exception
{
public override string Message
{
get
{
return "Exception A";
}
}
}
class ExceptionB : ExceptionA
{
public override string Message
{
get
{
return "Exception B";
}
}
}
class Program
{
static void Main(string[] args)
{
try
{
DoThing();
}
catch (Exception ex)
{
Console.WriteLine("Caught in 'UI' code: " + ex.Message);
}
}
static void DoThing()
{
try
{
throw new ExceptionB();
}
catch (ExceptionB ex)
{
Console.WriteLine("Caught B");
throw;
}
catch (ExceptionA ex)
{
Console.WriteLine("Caught A");
}
catch (Exception ex)
{
Console.WriteLine("Caught Generic");
}
}
}
}
Which yields this output:
Caught B
Caught in 'UI' code:
Exception B
Press any key to continue...
It just seems like you don't have anything catching the 2nd thrown exception, which is why it's "unhandled." If we comment out the try-catch in main, we end up with an unhandled exception:
static void Main(string[] args)
{
//try
//{
DoThing();
//}
//catch (Exception ex)
//{
//Console.WriteLine("Caught in 'UI' code: " + ex.Message);
//}
}
Yielding the following output:
Caught B
Unhandled Exception: ConsoleApplication1.ExceptionB: Exception B
at ConsoleApplication1.Program.DoThing() in C:\Users\Giovanni\AppData\Local\T
emporary Projects\ConsoleApplication1\Program.cs:line 50
at ConsoleApplication1.Program.Main(String[] args) in C:\Users\Giovanni\AppDa
ta\Local\Temporary Projects\ConsoleApplication1\Program.cs:line 33
Press any key to continue . . .
One item to not although this might not fix the exception, if you are catching and rethrowing the exception use this code instead:
catch (GatewayConnectionFailedException)
{
throw;
}
this way the stacktrace reflects the programs journey more accurately. It may not solve the issue though.
Hard to tell what is missing without full picture, but one important thing that you should throw exceptions in different way. The syntax should be
throw;
you will have full stacktrace. More info.
Catching of GatewayConnectionFailedException should solve your problem and in catch block just do throw, don't throw the exception object. Answer by Andy is correct.
Secondly I'm assuming GatewayConnectionFailedException inherits from GatewayException.
Select catch sequence in ascending of order of inheritance, child class should come first and then base class.
catch(Child){}
catch(Base){}
catch(Exception) {} //Base class for all exceptions
to start your try catch is redundant. the first catch will handle GatewayConnectionFailedException the remaining catches will never be of type GatewayConnectionFailedException because they were handled by the first catch. so the code can be simplified to
try
{
something();
}
catch (GatewayConnectionFailedException)
{
throw;
}
catch (GatewayException e)
{
_logger.Error(e.Message, e);
}
Now how the UI will handle this depends on how you handle the exception. if you just throw the exception, then you need a try catch in the presentation layer as well. However if the return type of this layer returned an object like
class Result<T>
{
T Value {get;set;}
Exception Error {get;set;}
}
Then you could simply process the type without need try/catch in the presentation layer.
Also worth noting is what you are catching and why you are trying to catch it. typically you don't want to catch Exception except at the application layer where you log the error and fail. Exceptions should be exceptional, and therefore only catch exceptions you expect can happen and why they may happen. otherwise let them bubble up.
Instead of using throw exceptionName try only throw.
Edit 1:
Try catching all exceptions in the same block, then throw back the exception only if it's the GatewayConnectionFailedException
try
{
something();
}
catch (Exception e)
{
if (e.GetType() == typeof(GatewayConnectionFailedException))
throw;
string errMsg = "Records could not be retrieved due to an unexpected error. " + GetTypeInfo();
_logger.Error(errMsg + "\r\n{0}", e);
}

Categories