Catching exceptions in Dispose during an exception [closed] - c#

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
Imagine that in C# (in .NET 4.5.x) that you have a using block around an object which implements IDisposible. Imagine that
an exception is thrown within the using block
when the dispose method is called, an additional exception is thrown
What is the best way to pass the two exceptions to a global error handler?
Code Sample:
class SampleClass : IDisposable
{
void doSomething()
{
// Imagine that this code is actually doing something
// Except that it unexpectedly hits an exception
throw new Exception("Exception A");
}
void Dispose()
{
// Imagine that this code is doing some cleanup
// Except that it is buggy
// And throws more exceptions
throw new Exception("Exception B");
}
}
static void Main()
{
try
{
using(var c = new SampleClass())
{
c.doSomething();
}
}
catch (Exception e)
{
// Code that records and reports exceptions
RecordException(e);
}
}
In the above example, I want all the details of both Exception A and Exception B recorded. What is the best way to pass the two exceptions to RecordException?
This article proposes a SafeUsingBlock extension. Is that the established best practice?
Edit: In this case I control and can re-write SampleClass and SampleClass.Dispose()

If you have control of the Dispose() method, I'd suggest making it error-proof at all costs. In general, you should be able to rely on IDisposables to Dispose() safely.
If this is a class you have no control over, your suggestion of try wrapping using will work, though, to make it more elegant, I'd probably do something closer to:
try
{
var c = new SampleClass();
c.doSomething();
c.Dispose();
}
catch(Exception e)
{
RecordException(e);
}
SafeUsingBlock() looks like it gets the job done, but I would not consider it to be established best practice: it's a workaround. Established best practice is for Dispose() methods to be safe.
Also, if SampleClass is one you have no control over, consider wrapping it in a façade which also implements IDisposable and handles errors in the Dispose() method, e.g.
public class SampleClassWrapper : IDisposable
{
private readonly SampleClass _target;
public SampleClassWrapper(SampleClass target)
{
_target = target;
}
public void doSomething()
{
_target.doSomething();
}
public void Dispose()
{
try
{
_target.Dispose();
}
catch(Exception e)
{
RecordException(e);
}
}
}
Then you can safely use your SampleClassWrapper in a using block without worrying about failures in Dispose()

Related

Handle exceptions from multiple methods [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a method that looks like this
private void Foo()
{
Method1(var1)
Method2(var1)
Method3(var2)
Method4(var3)
...
//lots of methods in a row like this
}
How would I implement Exception handling on every method it's calling, without spamming try-catch blocks everywhere? I'm wanting the exception message to be different depending on which method causes the exception.
Example:
Method1() breaks: show user "You don't have permissions for this"
Method2() breaks: show user "File contents are not in the right format"
Method3() breaks: show user "Error at line 3 in file"
etc...
A very low tech approach maybe to just use an Action Delegate with a generic parameter to at least filter by the exception you expect to get
public void Check<T>(Action action, string errorMessage ) where T : Exception
{
try
{
action();
}
catch (Exception e) when (e is T)
{
ShowMessage(errorMessage);
}
}
Usage
Check<IndexOutOfRangeException>(() => Method1(), "oh darn");
Personally though, I think this is a fairly suspect solution, and you should likely rethink your exception handling strategies in full. In short exceptions shouldn't be used for flow control, and catching them should be when you know exactly what do do with them.
Furthermore, the methods implementations should probably use Try style methods if they are available or catch and deal with their own exception when and only when it knows to expect them.
What you can do is creating a list of exceptions and adding all exception to that list.
At the end of the system you collect all your exception.
An example of this in your case.
private List<Exception> Exceptions = new List<Exception>();
Than each method you do following:
void Method1(string var1)
{
try
{
//some logic
}
catch (Exception e)
{
Exceptions.Add(e);
}
}
You also make your own error model that has exception property with other property like, time, message etc.
To show the problems at once, you can at the end of the all make a loop some thing like:
foreach (var exception in Exceptions)
{
Console.WriteLine(exception.Message);
}
If you are explicitly throwing new Exceptions based some conditions (handled exceptions), Then you don't need to spam everywhere by putting try-catch statements.
private void Foo()
{
try
{
Method1(var1);
Method2(var1);
Method3(var2);
Method4(var3);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void Method4(object var3)
{
throw new Exception("Exception A");
}
private void Method3(object var2)
{
throw new Exception("Exception B");
}
private void Method2(object var1)
{
throw new Exception("Exception C");
}
private void Method1(object var1)
{
throw new Exception("Exception D");
}
You can throw your identified exception in your each methods like below in its definition line where those methods implemented.
public void Method1() throws NoPermissionException{
}
public void Method2() throws IllegalFormatException {
}
public void Method3() throws ArithmeticException{
}
Then in the Foo() method write one try block and relevant catch clauses to catch each and every exception in one place of the code as below.
private void Foo()
{
try{
Method1(var1);
Method2(var1);
Method3(var2);
Method4(var3);
catch(NoPermissionException e){
e.printStackTrace();
}
catch(IllegalFormatException e){
e.printStackTrace();
}
catch(ArithmeticException){
e.printStackTrace();
}
...
//lots of methods in a row like this
}

How can I prevent repetition of a code block ending in return? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have a block of code which is used multiple times in multiple class methods. I would like to make it into a separate function, but the code block in question is an if statement with a return, e.g.
private void method() {
//..
if (condition) {
//..
return;
}
//..
}
The problem is that if I pull this out into a separate function, the return applies only to that function itself, and no longer to the class methods in question. What is the best way to deal with this situation?
A good solution is to extract the condition code to a new method that returns a bool and handle this in every method. The code might look a little like this:
private bool CheckCondition()
{
if (!condition) // Please recognize the NOT for this condition.
{
return true;
}
// .. your code from if statement
return false;
}
private void Method()
{
if (!this.CheckCondition())
{
return;
}
// ...
}
For completeness - there is another way but I would not recommend that:
private void WithCondition(Action action)
{
if (condition)
{
// ..
return;
}
action();
}
private void Method()
{
void Body()
{
// your old method body code after your condition here
}
this.WithCondition(Body);
}
But that looks weird. There are use cases for local functions like factory methods e.g. for non-blocking or some event handlers. But your case is not a common use case for that.

Is there a way to detect the exception in dispose?

I have the following scenario:
class Program
{
static void Main(string[] args)
{
try
{
using (new Foo())
{
throw new Exception("Inside using block");
}
}
catch (Exception e)
{
}
}
}
public class Foo : IDisposable
{
public void Dispose()
{
throw new Exception("Inside dispose");
}
}
Is it somehow possible, to get the thrown exception - "Inside using block" - in the Dispose method of Foo and make it an InnerException of the Exception Inside dispose?
Edit:
For example:
class Program
{
static void Main(string[] args)
{
try
{
using (var fi = new FileHandler())
{
//open the file
fi.Open();
//write to the file
fi.Write();
//excption occurs
throw new Exception("Inside using block");
fi.Close();
}
}
catch (Exception e)
{
//now I only have the exception from the dispose but not the exception that occured in the using block itself
//I know I could wrap the code inside the using in a try/catch itself, just asking if it is possible without 2 try/catches
}
}
}
public class FileHandler : IDisposable
{
public void Dispose()
{
//Close the file
//for some reason it fails with an exception
throw new Exception("Inside dispose");
}
}
Per the Framework Design Guidelines (Cwalina, Abrams), section 9.3:
AVOID throwing an exception from within Dispose(bool) except under critical situations where the containing process has been corrupted.
If Dispose could raise an exception, further finally block cleanup logic will not execute. To work around this, the user would need to wrap every call to Dispose (within their finally block!) in a try block, which leads to very complex cleanup handlers. If executing a Dispose(bool) method, never throw an exception if disposing is false.
Also from section 9.3:
AVOID making types finalizable. Carefully consider any case in which you think a finalizer is needed. There is a real cost associated with instances with finalizers, from both a performance and code complexity standpoint."

Is there a way to mark code as non-threadsafe in C#?

Im trying to hunt down a race condition, and I come across a lot of suspecious functions. Most of them are not allowed to be called from two threads at the same time, but its hard to make sure they don't.
Is there some keyword to instruct the runtime to throw an exception as soon as a function is executing in parallel? I know I sometimes get an exception when another thread modifies a collection which im enumerating, but are safeguards like that enough to rely on?
The runtime can halt execution using the lock instruction, so all I need is a lock which throws an error.
You can use Monitor.TryEnter for this:
bool entered = !Monitor.TryEnter(someLockObject);
try
{
if (!entered)
throw Exception("Multi-thread call!");
// Actual code
}
finally
{
if (entered)
{
Monitor.Exit(someLockObject);
}
}
And it would be good to wrap that code in its own class:
public sealed class MultiThreadProtector : IDisposable
{
private object syncRoot;
public MultiThreadProtector(object syncRoot)
{
this.syncRoot = syncRoot;
if (!Monitor.TryEnter(syncRoot))
{
throw new Exception("Failure!");
}
}
public void Dispose()
{
Monitor.Exit(this.syncRoot);
}
}
This way you can execute it as follows:
using (new MultiThreadProtector(someLockObject))
{
// protected code.
}

How I can get the calling methods in C# [duplicate]

This question already has answers here:
How can I find the method that called the current method?
(17 answers)
Closed 9 years ago.
Possible Duplicate:
How can I find the method that called the current method?
I need a way to know the name of calling methods in C#.
For instance:
private void doSomething()
{
// I need to know who is calling me? (method1 or method2).
// do something pursuant to who is calling you?
}
private void method1()
{
doSomething();
}
private void method2()
{
doSomething();
}
from http://www.csharp-examples.net/reflection-calling-method-name/
using System.Diagnostics;
// get call stack
StackTrace stackTrace = new StackTrace();
// get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);
You almost certainly don't want to do this. A caller should never know who is calling it. Instead, the difference between the two callers should be abstracted into a parameter, and passed into the method being called:
private void doSomething(bool doItThisWay)
{
if (doItThisWay)
{
// Do it one way
}
else
{
// Do it the other way
}
}
private void method1()
{
doSomething(true);
}
private void method2()
{
doSomething(false);
}
This way, if you add a method3, it can either doSomething one way or the other, and doSomething won't care.

Categories