This is somewhat of a follow up to a previous question I had asked, although I am now able to provide a lot more code to improve my question and further show my trouble with this area.
I have three routines here. Two of these routines work together - and if successful, will load an assembly into memory using System.Reflection. I would like for these routines to return an error if the file did not load properly into memory, but for some reason these try-catch statements simply will not work the way I would like.
Note: For this routine to work the file must be a .net assembly. If, for example, the file was programmed in VB6 an error will be thrown. This is the error I am trying to have returned to me.
private void ExecuteDataIntoMemory(string filePath)
{
byte[] bytes = File.ReadAllBytes(filePath);
try
{
ExecFile(bytes);
MessageBox.Show("successfully loaded this file into memory");
}
catch
{
MessageBox.Show("Could not load this file into memory");
}
}
private static void ExecFile(byte[] data)
{
try
{
//Work around for "SetCompatibleTextRenderingDefault"
System.Threading.Thread T = new System.Threading.Thread(ExecFile);
//Set STA to support drag/drop and dialogs?
T.SetApartmentState(System.Threading.ApartmentState.STA);
T.Start(data);
}
catch
{
MessageBox.Show("caught some error ...");
}
}
private static void ExecFile(object o)
{
System.Reflection.MethodInfo T = System.Reflection.Assembly.Load((byte[])o).EntryPoint;
if (T.GetParameters().Length == 1)
T.Invoke(null, new object[] { new string[] { } });
else
T.Invoke(null, null);
}
I can clarify more if necessary but I'm not sure what other information to include at this point.
Use the "throw" statement within the catch statement of ExecFile to raise the same "exception" (or error) caught in ExecFile. For example:
catch {
throw;
}
I think I figured out the problem though. ExecFile(byte[]) starts the thread and returns immediately without waiting for the thread to exit. To allow that method to wait for the thread to exit, add:
T.Join();
right after starting the thread. (To avoid possible ambiguity, however, you should rename ExecFile(object). I'm also not sure whether ExecFile(byte[]) will catch the exception from ExecFile(object).)
If I understand you well, You want the ExecuteDataIntoMemory to be evaluated only if the ExecFile succeed.
1- You are running a new thread to execute the ExecFile method which will be executed in a different thread. So first at the try block in ExecFile(byte[] data) run the ExecFile(data) without a new Thread because you want to wait for it any way:
try
{
ExecFile(data);
}
2- Notice that you have two method with the same name 'ExecFile(byte[] data)' and ExecFile(object o) the data you are passing is from type byte[] so it will be infinite recursive or till stack over flow exception is raised. So you should cast data to object and then pass it to the method i.e:
try
{
ExecFile((object)data);
}
3- At the catch block of the ExecFile(byte[] data) method rethrow the exception so it can be handled from the caller method two i.e:
try
{
ExecFile((object)data);
}
catch
{
MessageBox.Show("caught some error ...");
throw;
}
If you catch the Exception in ExecFile(byte[] data) it won't be propagated in your parent method (ExecuteDataIntoMemory(string filePath)), and then won't be catched again
If you really need to catch your exception twice, rewrite your child method this way
private static void ExecFile(byte[] data)
{
try
{
//Work around for "SetCompatibleTextRenderingDefault"
System.Threading.Thread T = new System.Threading.Thread(ExecFile);
//Set STA to support drag/drop and dialogs?
T.SetApartmentState(System.Threading.ApartmentState.STA);
T.Start(data);
}
catch (Exception ex)
{
MessageBox.Show("caught some error ...");
throw ex;
}
}
If not, simply not try..catch errors in this method, and the Exception will be propagated..
Just look in the callstack which method call the ExecuteDataIntoMemory method again?
if you are using Visual studio IDE put a breakpoint at the messagebox:
MessageBox.Show("successfully loaded this file into memory");
then simple go to the view menu, from there find the callstack window to display and look at the callstack (show external code to the callstack)
maybe this could help.
The rough way (I think), but should work in your case, is subscribe to
AppDomain.CurrentDomain.UnhandledException
event riased, which will get the exception raised directly from the function ExecFile(object o);
Or create a state machine which is set to NEGATIVE state in case of any exception in ExecFile(object o); method.
Or just do not do it in multithreading :)
Related
I have a new application that contains great amount of try-catch blocks. I am interested in if it is possible to write code which somehow attachs SaveExceptionInDatabase method to every catch-block I have used in my application.
try
{
//some actions
}
catch(exception e)
{
SaveExceptionInDatabase(e,DateTime.now(),CurrentUser);
ShowFriendlyNotification();
}
I think it will be helpful to easily remove bugs from my application, because I have noticed for several times that after the exception is thrown, attempting to perform the same operation second time finishes with success.
EDIT:
I am using WPF With Caliburn.Micro
You could use PostSharp and handle the exceptions. Here are some related articles that show how it can be done. This method seems really cool because you can just add an attribute to your classes an have the exceptions handled.
[DatabaseExceptionWrapper]
http://www.postsharp.net/blog/post/Day-1-e28093-OnExceptionAspect
http://www.postsharp.net/blog/post/Improve-Exception-Handling-and-Caching-using-PostSharp
You can use something like:
private void HandleDbException(Action action)
{
try
{
action();
}
catch (Exception e)
{
SaveExceptionInDatabase(e, DateTime.now(), CurrentUser);
ShowFriendlyNotification();
}
}
And then
HandleDbException(() =>
{
//some actions1
});
HandleDbException(() =>
{
//some actions2
});
...
It won't apply the pattern to each try/catch block in your code but at least avoids repeating the catch block.
I've written what I initially thought was a generic method executer and error handler for any method I add or might add in the future but after many hours of struggling and googling, I have resorted to going to forums.
Aim: To try and get away from individual error handling in a method and handle all errors in one single method. (hope this makes sense).
Code for Generic method executer and error handler:
internal static Tuple<SystemMessage, object> ExecuteAndHandleAnyErrors<T,TArg1>(this object callingMethod, params object[] args)
{
dynamic methodToExecute;
if (callingMethod.GetType() == typeof(Func<T, TArg1>))
{
methodToExecute = (callingMethod as Func<T,TArg1>);
}
else
{
methodToExecute = (callingMethod as Action<T, TArg1>);
}
try
{
var result = methodToExecute.DynamicInvoke(args);
return new Tuple<SystemMessage, object>(null,result);
}
catch (Exception ex)
{
return new Tuple<SystemMessage, object>(new SystemMessage
{
MessageText = ex.Message,
MessageType = SystemMessage.SystemMessageType.Error
}, null);
}
}
//This is the code for a sample method:
internal QuestionAnswerSet LoadQuestions(DataWrapper dataWrapper)
{
var taskExecuter = new Func<DataWrapper, QuestionAnswerSet> (InternalDeserializeObject<QuestionAnswerSet>);
var questionAnswerSet = taskExecuter.ExecuteAndHandleAnyErrors<DataWrapper, QuestionAnswerSet>(dataWrapper);
return questionAnswerSet.Item2 as QuestionAnswerSet;
}
my question is this: Is it possible that if the LoadQuestions method falls over, how do I catch the error and defer the error handling to the ExecuteAndHandleAnyErrors method without manually adding a try...catch statement to the LoadQuestions method?
Hope this makes sense.
thank u.
charles
You could wrap every call of LoadQuestions in its own call to ExecuteAndHandleAnyErrors.
However, this seems to be missing part of the point of exception handling. When using exceptions to communicate error, one usually doesn't "handle all errors in one single method". That one single method usually cannot deal with any possible exception sensibly. For example, could your method handle a ThreadAbortedException? What about an ArgumentException? Nor does one add a lot of try ... catch block all over the place.
In general, try to write try ... catch blocks that handle specific exceptions when your code can handle the failure sensibly (e.g., catching FileNotFoundException near where you open a file and triggering a dialog box or attempting to open a default file at a different path).
Often, an application will have one top-level try ... catch block in Main() to log any otherwise unhandled exceptions. Then it rethrows the exception/crashes the program/exits the program.
I solved it.
What I was doing was is seeing the first time the exception is thrown and not stepping further down by pressing F10.
THanks for all the help
I have following code in my web page:
btnTest_Click(object sender, EventArgs e)
{
...
bool ret=myFunc(...);
if (ret)
{...}
else
{
lblStatus.Text="Some Text";
lblStatus.Visible=true;
}
}
private bool myFunc(...)
{
bool ret=false;
try
{
...
ret=true;
}
catch (Exception ex)
{
lblStatus.Text="Other Text";
lblStatus.Visible=true;
}
return ret;
}
If an exception occurs in myFunc, the lblStatus always shows "Some Text" not "Other Text". That means the catch block in myFunc doesn't really mean anything. I wonder how to fix this code to handle the exception better?
update: maybe my example is not very good. But I main purpose is to ask best practices for exceptions handling between calling and being called functions.
Why is your called function setting the label text on exception and the caller setting it on success?
That's something of a mixed metaphor. Let one party be responsible for UI (separation of concerns) while the other is responsible for doing work. If you want your called function to be fault tolerant try something like this:
private bool myFunc(...)
{
bool ret ;
try
{
...
ret=true;
}
catch
{
ret = false ;
}
return ret;
}
Then your caller can do something like:
bool success = myFunc(...) ;
lblStatus.Text = success ? "Some Text" : "Other Text" ;
lblStatus.Visible = success ;
if ( success )
{
// do something useful
}
Your catch clause is doing a lot. It catches every exception and "forgets it" suppressing it to the rest of the call stack. This can be perfectly fine but i'll try to explain your options:
You usually have 3 options:
Do not care about exceptions and let code above you handle it
Care to log the exception and let it propagate
The exception has its meaning in a given context and should not be propagated (this is your scenario)
I use all of them.
Option 1
You can just implement your function and if an exception occurs then it means some fault occurred and you just want your application to fail (at least to a certain level)
Option 2
Some exception occurs and you'll want to do one of two (or even both)
log the error
change the exception to another one more meaningful to the caller
Option 3
The exception is expected and you know how to completely react to it. For instance, in your case, i tend to believe you do not care about the type of exception but want a "good default" by setting some controls to a given text.
conclusion
There are no silver bullets. Use the best option for each scenario.
Nevertheless catching and "suppressing" catch(Exception ex) is rare and if seen often it usually means bad programming.
It displays "Some Text" because, when an exception occurs in myFunc, it returns false. Then you go into the else block of the btnTest_Click method, where you set lblStatus.Text to "Some Text" again.
So, basically, you're setting the label's text to "Other text" and then to "Some Text".
The exception handling is just fine. The problem with your code is that you are putting the "Some Text" string in the label if the return value is false, and that is when there was an exception, so it will replace the message from the catch block.
Switch the cases:
if (ret) {
// it went well, so set the text
lblStatus.Text="Some Text";
lblStatus.Visible=true;
} else {
// an exception occured, so keep the text set by the catch block
}
This is a complex question so I will try to break it down
In terms of functions I would try to stick to the Single Responsibility Principal. It should do one, well defined thing.
Exceptions should be that, exceptional. It is then preferable to try not to incur exceptions but obviously to deal with them as and when. For example it is better to test a variable as being null before attempting to use it (which would throw an exception). Exceptions can be slow (especially if a lot are thrown)
I would say that the question of WHERE you handle the exception is down to whose responsibility the exception is. If myFunc were to access a remote server and return a status of true or false you'd expect it to handle its own IO exception. It would probably not handle (or rethrow) any parameter problems. This relates to point 1. It is the functions responsibility deal with the connection process, not to provide the correct parameters. Hiding certain exceptions can cause problems if other people (or a forgetful you) tries to use the code at a later date. For example in this myFunc which makes a connection, should you hide parameter exceptions you may not realise you have passed in bad parameters
If you want to be informed of encountering a specific type of error inside one of your functions, I'd recommend inheriting Exception and creating your own exception class. I'd put a try-catch block inside your btnTest_Click() handler, and then I'd look to catch your custom exception class. That way, you won't lose the opportunity to detect any errors happening inside your myFunc() function.
I usually setup an error handling system. Here's a simple way, but this can be wrapped up into a base class. I can show you that if you need.
List<string> _errors;
void init()
{
_errors = new List<string>();
}
protected void Page_Load(object sender, EventArgs e)
{
init();
}
btnTest_Click(object sender, EventArgs e)
{
...
var result = myFunc(...);
if (result)
{...}
else
{
if (_errors.Count > 0)
{
var sb = new StringBuilder("<ul>");
foreach (string err in _errors)
{
sb.AppendLine(string.Format("<li>{0}</li>", err));
}
sb.AppendLine("</ul>");
lblStatus.Text=sb.ToString();//Make this a Literal
}
}
}
private bool myFunc(...)
{
var result = true;
try
{
...
...
}
catch (Exception ex)
{
result = false;
_errors.Add(ex.Message);
}
return result;
}
I have the need to do some logging within my code. I'm required to use an internal company-developed library to record some information. Here's how it works.
Recorder recorder = Recorder.StartTiming();
DoSomeWork();
recorder.Stop(); // Writes some diagnostic information.
To ensure that Stop() is always called, I created a wrapper class that allows a clean "using" block.
using (RecorderWrapper recorderWrapper = new RecorderWrapper) // Automatically calls Recorder.StartTiming() under the covers
{
DoSomeWork();
} // When the recorderWrapper goes out of scope, the 'using' statement calls recorderWrapper.Dispose() automatically - which calls recorder.Stop() under the covers
it's worked well so far. However, there's a change my company is requiring, that would look something like this on the original code:
Recorder recorder = Recorder.StartTiming();
try
{
DoSomeWork();
}
catch (Exception ex)
{
recorder.ReportFailure(ex); // Write out some exception details associated with this "transaction"
}
recorder.Stop(); // Writes some diagnostic information.
I'd like to avoid try/catches in all my 'using' scope blocks with RecorderWrapper. Is there a way I can accomodate the "ReportFailure()" call and still leverage the 'using' scope block?
Specifically, I want everyone on my team to "fall into a pit of success", i.e. make it easy to do the right thing. To me, this means making it really hard to forget to call recorder.Stop() or forget the try/catch.
Thanks!
You might be able to create a method on the recorder to hide this:
public void Record(Action act)
{
try
{
this.StartTiming();
act();
}
catch(Exception ex)
{
this.ReportFailure(ex);
}
finally
{
this.Stop();
}
}
So your example would then just be:
recorder.Record(DoSomeWork);
You could always try something like:
Edit by 280Z28: I'm using a static StartNew() method here similar to Stopwatch.StartNew(). Make your Recorder class IDisposable, and call Stop() from Dispose(). I don't think it gets any more clear than this.
using (Recorder recorder = Recorder.StartNew())
{
try
{
DoSomeWork();
}
catch (Exception ex)
{
recorder.ReportFailure(ex);
}
}
You could continue to use the RecorderWrapper you have, but add a TryExecuting method that accepts a lambda of what you want to happen add runs it in a try/catch block. eg:
using (RecorderWrapper recorderWrapper = new RecorderWrapper) // Automatically calls Recorder.StartTiming() under the covers
{
recorderWrapper.TryExecuting(() => DoSomeWork());
}
Inside RecorderWrapper:
public void TryExecuting(Action work)
{
try { work(); }
catch(Exception ex) { this.ReportFailure(ex); }
}
You could copy the pattern used by TransactionScope, and write a wrapper that must be actively completed - if you don't call Complete(), then the Dispose() method (which gets called either way) assumes an exception and does your handling code:
using(Recorder recorder = Recorder.StartTiming()) {
DoSomeWork();
recorder.Complete();
}
Personally, though, I'd stick with try/catch - it is clearer for maintainers in the future - and it provides access to the Exception.
No, a using block is only syntactic sugar for a try/finally block. It doesn't deal with try/catch. At that point you're going to be left with handling it yourself since it looks like you need the exception for logging purposes.
A using block is effectively a try/finally block that calls dispose on the object in question.
So, this:
using(a = new A())
{
a.Act();
}
is (i think, exactly) equivalent to this:
a = new A();
try
{
a.Act();
}
finally
{
a.Dispose();
}
And you can tack your catches onto the end of the try block.
Edit:
As an alternative to Rob's solution:
Recorder recorder = Recorder.StartNew()
try
{
DoSomeWork();
}
catch (Exception ex)
{
recorder.ReportFailure(ex);
}
finally
{
recorder.Dispose();
}
Oops, I hadn't noticed that a new instance of Recorder was being created by StartTiming. I've updated the code to account for this. The Wrap function now no longer takes a Recorder parameter but instead passes the recorder it creates as an argument to the action delegate passed in by the caller so that the caller can make use of it if needed.
Hmmm, I've needed to do something very similar to this pattern, lambdas, the Action delegate and closures make it easy:
First define a class to do the wrapping:
public static class RecorderScope
{
public static void Wrap(Action<Recorder> action)
{
Recorder recorder = Recorder.StartTiming();
try
{
action(recorder);
}
catch(Exception exception)
{
recorder.ReportFailure(exception);
}
finally
{
recorder.Stop();
}
}
}
Now, use like so:
RecorderScope.Wrap(
(recorder) =>
{
// note, the recorder is passed in here so you can use it if needed -
// if you never need it you can remove it from the Wrap function.
DoSomeWork();
});
One question though - is it really desired that the catch handler swallows the exception without rethrowing it? This would usually be a bad practice.
BTW, I'll throw in an addition to this pattern which can be useful. Although, it doesn't sound like it applies to what you're doing in this instance: Ever wanted to do something like the above where you want to wrap some code with a set of startup actions and completion actions but you also need to be able to code some specific exception handling code. Well, if you change the Wrap function to also take an Action delegate and constrain T to Exception, then you've got a wrapper which allows user to specify the exception type to catch, and the code to execute to handle it, e.g.:
public static class RecorderScope
{
public static void Wrap(Action<Recorder> action,
Action<Recorder, T1> exHandler1)
where T1: Exception
{
Recorder recorder = Recorder.StartTiming();
try
{
action(recorder);
}
catch(T1 ex1)
{
exHandler1(recorder, ex1);
}
finally
{
recorder.Stop();
}
}
}
To use.. (Note you have to specify the type of exception, as it obviously cannot be inferred. Which is what you want):
RecorderScope.Wrap(
(recorder) =>
{
DoSomeWork();
},
(recorder, MyException ex) =>
{
recorder.ReportFailure(exception);
});
You can then extend this pattern by providing multiple overloads of the Wrap function which take more than one exception handler delegate. Usually five overloads will be sufficient - it's pretty unusual for you to need to catch more than five different types of exceptions at once.
Don't add another level of indirection. If you need to catch the Exception, use try..catch..finally and call Dispose() in the finally block.
Working on a project where a sequential set of methods must be run every x seconds. Right now I have the methods contained within another "parent method", and just sequentially call them right after another.
class DoTheseThings()
{
DoThis();
NowDoThat();
NowDoThis();
MoreWork();
AndImSpent();
}
Each method must run successfully without throwing an exception before the next step can be done. So now I wrapped each of those methods with a while and try..catch, then in the catch execute that method again.
while( !hadError )
{
try
{
DoThis();
}
catch(Exception doThisException )
{
hadError = true;
}
}
This seems smelly and not very dry. Is there a better way to do this so I'm not wrapping any new functionality in the same methods. Isn't some kind of Delegate collection the proper way to implement this?
Is there a more "proper" solution?
Action[] work=new Action[]{new Action(DoThis), new Action(NowDoThat),
new Action(NowDoThis), new Action(MoreWork), new Action(AndImSpent)};
int current =0;
while(current!=work.Length)
{
try
{
work[current]();
current++;
}
catch(Exception ex)
{
// log the error or whatever
// maybe sleep a while to not kill the processors if a successful execution depends on time elapsed
}
}
Isn't some kind of Delegate collection the proper way to implement this?
Delegate is a possible way to solve this problem.
Just create a delegate something like:
public delegate void WorkDelegate();
and put them in arraylist which you can iterate over.
I have a personal religious belief that you shouldn't catch System.Exception, or more accurately, you should only catch the exceptions you know how to handle.
That being said, I am going to assume that each one of the methods that you are calling are doing something different, and could result in different exceptions being thrown. Which means you would likely need to have different handlers for each method.
If you follow my religion as well, and the second statement is true, then you are not repeating code unnecessarily. Unless you have other requirements, my recommendations to improve your code would be:
1) Put the try-catch in each method, not around each method call.
2) Have the catches within each method catch ONLY the exceptions you know about.
http://blogs.msdn.com/fxcop/archive/2006/06/14/631923.aspx
http://blogs.msdn.com/oldnewthing/archive/2005/01/14/352949.aspx
http://www.joelonsoftware.com/articles/Wrong.html
HTH ...
your example seems ok.. its a dry one but will do the job well!! actually if this methods execute db access.. you can use transaction to ensure integrity...
if your dealing with shared variables for multi threader programs.. it is cleaner to use synchronization.. the most important thing in coding is that you write the proper code... that has less bugs.. and will do the task correctly..
public void DoTheseThings()
{
SafelyDoEach( new Action[]{
DoThis,
NowDoThat,
NowDoThis,
MoreWork,
AndImSpent
})
}
public void SafelyDoEach( params Action[] actions )
{
try
{
foreach( var a in actions )
a();
}
catch( Exception doThisException )
{
// blindly swallowing every exception like this is a terrible idea
// you should really only be swallowing a specific MyAbortedException type
return;
}
}
What would be the reason that an error was occuring?
If this were a resource issue, such as access to something like a connection or object, then you might want to look at using monitors, semaphores, or just locking.
lock (resource)
{
Dosomething(resource);
}
This way if a previous method is accessing the resource, then you can wait until it releases the resource to continue.
Ideally, you shouldn't have to run a loop to execute something each time it fails. It is failing at all, you would want to know about the issue and fix it. Having a loop to always just keep trying is not the right way to go here.
I'd do what Ovidiu Pacurar suggests, only I'd use a foreach loop and leave dealing with array indexes up to the compiler.
Simple delegate approach:
Action<Action> tryForever = (action) => {
bool success;
do {
try {
action();
success = true;
} catch (Exception) {
// should probably log or something here...
}
} while (!success);
};
void DoEverything() {
tryForever(DoThis);
tryForever(NowDoThat);
tryForever(NowDoThis);
tryForever(MoreWork);
tryForever(AndImSpent);
}
Stack approach:
void DoEverything() {
Stack<Action> thingsToDo = new Stack<Action>(
new Action[] {
DoThis, NowDoThat, NowDoThis, MoreWork, AndImSpent
}
);
Action action;
while ((action = thingsToDo.Pop()) != null) {
bool success;
do {
try {
action();
success = true;
} catch (Exception) {
}
} while (!success);
}