Rethrow an exception in a try block c# - c#

My first question here and I am not that great at english so please bear with me,
I am writing an application that allows users to write scripts that interface with 'drivers', the scripts and drivers are all separate class library dll's. These classes communicate through callback delegates that are passed , so at compile-time they are not linked.
example: (Script)-->(The program that handles
communication)-->(drivers)
Now my question is:
When a script executes a method via a delegate and it throws an exception, the exception is bubbled back up to the script and the user can handle it if they catch it in a try-catch block, if not, the exception has to be caught inside my program.
It works fine like this, but I do not know if this is the right way to go:
delegate object ScriptCallbackDelegate(string InstanceName, string MethodName, object[] Parameters);
static private object ScriptCallbackMethod(string InstanceName, string MethodName, object[] Parameters)
{
try
{
return InterfaceWithDriver(InstanceName, MethodName, Parameters);
}
catch( Exception e )
{
try
{
throw;
}
catch
{
Console.WriteLine("Script did not handle exception: " + e.Message);
return null;
}
}
}

catch (Exception e)
{
try
{
throw;
}
catch
{
Console.WriteLine("Script did not handle exception: " + e.Message);
return null;
}
}
is semantically identical to:
catch (Exception e)
{
Console.WriteLine("Script did not handle exception: " + e.Message);
return null;
}
The script is never seeing that inner throw - it is being caught by your C# code.

Exception caused in your code never leaves it, e.g. in following you can see a similar behavior.
using System;
namespace Code.Without.IDE
{
public static class TryCatch
{
public static void Main(string[] args)
{
try
{
try
{
throw new Exception("Ex01");
}
catch(Exception ex)
{
try
{
throw;
}
catch
{
Console.WriteLine("Exeption did not go anywhere");
}
}
Console.WriteLine("In try block");
}
catch
{
Console.WriteLine("In catch block");
}
}
}
}
generates following output:
------ C:\abhi\Code\CSharp\without IDE\TryCatch.exe
Exeption did not go anywhere
In try block
------ Process returned 0

Related

Logging exception without catching it

I want to log an unhandled exception in my domain layer without catching it.
I mean that the exception should be thrown after logging to be caught again in upper levels. As you know, throwing has an overhead that I want to avoid.
Any idea in Dotnet platform (C#) ?
public static void Main(string[] args)
{
try
{
throw new System.Exception("some exception");
}
catch (System.Exception ex) when (LogUsingSerilogOrNLogOrBla(ex)) { }
finally
{
Console.WriteLine("exception logged, but not handled :), there is no need to throw");
}
}
public static bool LogUsingSerilogOrNLogOrBla(System.Exception ex)
{
Console.WriteLine(ex);
return false;
}

Pass exception to the next handler without propagation?

Suppose I have this application:
class Program
{
static void Main(string[] args)
{
try
{
throw new SomeSpecificException("testing");
}
catch (SomeSpecificException ex)
{
Console.WriteLine("Caught SomeSpecificException");
throw new Exception("testing");
}
catch (Exception ex)
{
Console.WriteLine("Caught Exception");
}
Console.ReadKey();
}
}
// just for StackOverflow demo purposes
internal class SomeSpecificException : Exception
{
public SomeSpecificException(string message) : base(message)
{ }
public SomeSpecificException()
{ }
}
And my required output is as follows:
Caught SomeSpecificException
Caught Exception
Is there a way to do this? Or is my design totally off base?
Background:
I am adding code to an existing code base. The code base catches Exception (generalized exception) and does some logging, removes files, etc. But I have a unique behavior I'd like to only happen when SomeSpecificException is thrown. Afterwards, I'd like the exception handling to pass to the existing Exception catch clause so that I do not have to modify too much of the existing code.
I am aware of checking for exception's type using reflection or some other runtime technique and putting an if statement in the Exception catching clause as per Catch Multiple Exceptions at Once but I wanted to get feedback on whether the above approach is possible.
You need to use two try blocks:
try {
try {
throw ...;
} catch(SpecificException) {
// Handle
throw;
}
} catch(Exception) {
// Handle
}
Your approach will not work. The best you can do is to extract the code you want to have in common between the two handlers into a method, and have them both call the common method.
try
{
throw new SomeSpecificException("testing");
}
catch (SomeSpecificException ex)
{
Console.WriteLine("Caught SomeSpecificException");
CommonHandling();
}
catch (Exception ex)
{
CommonHandling();
}
private void CommonHandling() {
Console.WriteLine("Caught Exception");
}
Try this:
try
{
try
{
throw new InvalidCastException("testing");
}
catch (SomeSpecificException ex)
{
Console.WriteLine("Caught SomeSpecificException");
throw new Exception("testing");
}
}
catch (Exception ex)
{
Console.WriteLine("Caught Exception");
}
Console.ReadKey();
This should avoid changing the existing code much. You are just adding an additional try directly inside the existing one.
If you really want it to work this was, I suppose you could so something with a switch statement
try
{
throw new InvalidCastException("testing");
}
catch (Exception ex)
{
switch(ex.GetType())
{
case "SomeSpecificException":
Console.WriteLine("Caught SomeSpecificException");
goto default; //if I recall correctly, you need a goto to fall through a switch in c#
break;
default:
Console.WriteLine("Caught Exception");
}
Console.ReadKey();

What is the best practice in C# to propagate an exception thrown in a finally block without losing an exception from a catch block?

When an exception is possible to be thrown in a finally block how to propagate both exceptions - from catch and from finally?
As a possible solution - using an AggregateException:
internal class MyClass
{
public void Do()
{
Exception exception = null;
try
{
//example of an error occured in main logic
throw new InvalidOperationException();
}
catch (Exception e)
{
exception = e;
throw;
}
finally
{
try
{
//example of an error occured in finally
throw new AccessViolationException();
}
catch (Exception e)
{
if (exception != null)
throw new AggregateException(exception, e);
throw;
}
}
}
}
These exceptions can be handled like in following snippet:
private static void Main(string[] args)
{
try
{
new MyClass().Do();
}
catch (AggregateException e)
{
foreach (var innerException in e.InnerExceptions)
Console.Out.WriteLine("---- Error: {0}", innerException);
}
catch (Exception e)
{
Console.Out.WriteLine("---- Error: {0}", e);
}
Console.ReadKey();
}
I regularly come into the same situation and have not found a better solution yet. But I think the solution suggested by the OP is eligible.
Here's a slight modification of the original example:
internal class MyClass
{
public void Do()
{
bool success = false;
Exception exception = null;
try
{
//calling a service that can throw an exception
service.Call();
success = true;
}
catch (Exception e)
{
exception = e;
throw;
}
finally
{
try
{
//reporting the result to another service that also can throw an exception
reportingService.Call(success);
}
catch (Exception e)
{
if (exception != null)
throw new AggregateException(exception, e);
throw;
}
}
}
}
IMHO it will be fatal to ignore one or the other exception here.
Another example: Imagin a test system that calibrates a device (DUT) and therefore has to control another device that sends signals to the DUT.
internal class MyClass
{
public void Do()
{
Exception exception = null;
try
{
//perform a measurement on the DUT
signalSource.SetOutput(on);
DUT.RunMeasurement();
}
catch (Exception e)
{
exception = e;
throw;
}
finally
{
try
{
//both devices have to be set to a valid state at end of the procedure, independent of if any exception occurred
signalSource.SetOutput(off);
DUT.Reset();
}
catch (Exception e)
{
if (exception != null)
throw new AggregateException(exception, e);
throw;
}
}
}
}
In this example, it is important that all devices are set to a valid state after the procedure. But both devices also can throw exceptions in the finally block that must not get lost or ignored.
Regarding the complexity in the caller, I do not see any problem there either. When using System.Threading.Tasks the WaitAll() method, for example, can also throw AgregateExceptions that have to be handled in the same way.
One more note regarding #damien's comment: The exception is only caught to wrap it into the AggregateException, in case that the finally block throws. Nothing else is done with the exception nor is it handled in any way.
For those who want to go this way you can use a little helper class I created recently:
public static class SafeExecute
{
public static void Invoke(Action tryBlock, Action finallyBlock, Action onSuccess = null, Action<Exception> onError = null)
{
Exception tryBlockException = null;
try
{
tryBlock?.Invoke();
}
catch (Exception ex)
{
tryBlockException = ex;
throw;
}
finally
{
try
{
finallyBlock?.Invoke();
onSuccess?.Invoke();
}
catch (Exception finallyBlockException)
{
onError?.Invoke(finallyBlockException);
// don't override the original exception! Thus throwing a new AggregateException containing both exceptions.
if (tryBlockException != null)
throw new AggregateException(tryBlockException, finallyBlockException);
// otherwise re-throw the exception from the finally block.
throw;
}
}
}
}
and use it like this:
public void ExecuteMeasurement(CancellationToken cancelToken)
{
SafeExecute.Invoke(
() => DUT.ExecuteMeasurement(cancelToken),
() =>
{
Logger.Write(TraceEventType.Verbose, "Save measurement results to database...");
_Db.SaveChanges();
},
() => TraceLog.Write(TraceEventType.Verbose, "Done"));
}
As the comments have suggested this may indicate "unfortunately" structured code. For example if you find yourself in this situation often it might indicate that you are trying to do too much within your method. You only want to throw and exception if there is nothing else you can do (your code is 'stuck' with a problem you can't program around. You only want to catch an exception if there is a reasonable expectation you can do something useful. There is an OutOfMemoryException in the framework but you will seldom see people trying to catch it, because for the most part it means you're boned :-)
If the exception in the finally block is a direct result of the exception in the try block, returning that exception just complicates or obscures the real problem, making it harder to resolve. In the rare case where there is a validate reason for returning such as exception then using the AggregateException would be the way to do it. But before taking that approach ask yourself if it's possible to separate the exceptions into separate methods where a single exception can be returned and handled (separately).

Best practice for throwing exceptions in an utility class

I am creating a utility class that will be used in my Facebook application for tasks that are commonly done, such as retrieving a Facebook Page ID from a URL. I am unsure if the below code is the correct way to throw and catch exceptions. Could someone please advise, thanks.
Utility Class:
public static class FacebookUtilities
{
public static string GetPageIDFromGraph(string pageUri, string accessToken)
{
try
{
FacebookClient client = new FacebookClient(accessToken);
dynamic result = client.Get(GetPageIDFromUri(pageUri), new { fields = "id" });
return result.ToString();
}
catch (FacebookOAuthException)
{
throw;
}
catch (FacebookApiException)
{
throw;
}
}
public static string GetPageIDFromUri(string pageUri)
{
if (pageUri.Contains('/'))
pageUri = pageUri.Substring(pageUri.LastIndexOf('/') + 1);
if (pageUri.Contains('?'))
return pageUri.Substring(0, pageUri.IndexOf('?'));
else
return pageUri;
}
}
Program class, just testing:
- Note "input" and "output" are just textboxes.
private void btnGetPageID_Click(object sender, EventArgs e)
{
try
{
output.Text = FacebookUtilities.GetPageIDFromGraph(input.Text, "Some Access Token Goes Here");
}
catch (FacebookOAuthException ex)
{
if (ex.ErrorCode == 803)
{
output.Text = "This page does not exist";
}
}
catch (FacebookApiException ex)
{
if (ex.ErrorCode == 100)
{
output.Text = "The request was not supported. The most likely cause for this is supplying an empty page ID.";
}
}
}
Is it correct to simply rethrow the exception from the utility class so that the calling class can catch it and do what needs to be done?
It seems that you do nothing with catched exceptions - so dont catch them. There are a lot of discussions about exception handling, but in general you should catch exceptions when you have something to do with them, or at least using finally to clean up resourses.
Since you aren't handling the exceptions in any way, your code can just be:
public static string GetPageIDFromGraph(string pageUri, string accessToken)
{
FacebookClient client = new FacebookClient(accessToken);
dynamic result = client.Get(GetPageIDFromUri(pageUri), new { fields = "id" });
return result.ToString();
}
You should only catch exceptions when you can meaningfully handle them, and it doesn't look like you can in your GetPageIDFromGraph method, so you should just propagate them.

Throw exception from Called function to the Caller Function's Catch Block

internal static string ReadCSVFile(string filePath)
{
try
{
...
...
}
catch(FileNotFoundException ex)
{
throw ex;
}
catch(Exception ex)
{
throw ex;
}
finally
{
...
}
}
//Reading File Contents
public void ReadFile()
{
try
{
...
ReadCSVFile(filePath);
...
}
catch(FileNotFoundException ex)
{
...
}
catch(Exception ex)
{
...
}
}
Here in the above code sample, I have two functions ReadFile and ReadCSVFile.
In the ReadCSVFile, I get an exception of type FileNotFoundException, which gets caught in the catch(FileNotFoundException) block. But when I throw this exception to be caught in the catch(FileNotFoundException) of the ReadFile Function, it gets caught in the catch(Exception) block rather than catch(FileNotFoundException). Moreover, while debugging, the value of the ex says as Object Not Initialized. How can I throw the exception from the called function to the caller function's catch block without losing the inner exception or atleast the exception message?
You have to use throw; instead of throw ex;:
internal static string ReadCSVFile(string filePath)
{
try
{
...
...
}
catch(FileNotFoundException ex)
{
throw;
}
catch(Exception ex)
{
throw;
}
finally
{
...
}
}
Besides that, if you do nothing in your catch block but rethrowing, you don't need the catch block at all:
internal static string ReadCSVFile(string filePath)
{
try
{
...
...
}
finally
{
...
}
}
Implement the catch block only:
when you want to handle the exception.
when you want to add additional information to the exception by throwing a new exception with the caught one as inner exception:
catch(Exception exc) { throw new MessageException("Message", exc); }
You do not have to implement a catch block in every method where an exception can bubble through.
Just use throw in the called function. Dont overload catch blocks with multiple exception types. Let the caller take care of that.
You should replace
throw ex;
by
throw;
In the called function just use throw like this
try
{
//you code
}
catch
{
throw;
}
Now, if the exception arise here then this will be caught by the caller function .
Your code works fine here, Check here http://ideone.com/jOlYQ

Categories