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
Related
I am using VS 2013 and coding in c#
My first function, calls the second function with 4 argument and the second one return type is void.
sometimes second functions gives an exception and program crashes.
I want to pass it's exception to the first function so that it could write it in a message box.
Is this possible? (And if it is, how I should do that?)
Thanks.
Wrap call to the second function into try/catch block and handle the exception being thrown by that function:
Something like this (pseudocode):
public void FirstFunction()
{
....
try
{
SecondFunction();
}
catch(Exception ex)
{
// here is text of exception being thrown in SecondFunction
string errorText = ex.Message;
}
}
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 following code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
try
{
this.CheckValue(true); // call method
}
catch(Exception ex)
{
// how to get here name of last called method
}
}
public int CheckValue(bool sender)
{
var qwe = int.Parse("qwe"); // invoke an exception
return 0;
}
}
I need to get in "catch block" name of last called method (in this case "CheckValue"), but it return that called method is "StringToNumber".
I try to get it using StackTrace:
stackTrace.GetFrame(1).GetMethod().Name; -> "Main"
MethodBase.GetCurrentMethod(); -> "Void .ctor()"
ex.TargetSite.Name; -> "StringToNumber"
It's possible to do this?
Short Answer:
Yes, You can!!!
I'd just play around with Extension Methods and the trick here, is to get the last frame of the desired class, otherwise it would get methods of mscorlib assembly. So here it go:
public static string GetLastCalledMethod<T>(this Exception ex)
{
var stackTrace = new System.Diagnostics.StackTrace(ex);
var lastFrame = stackTrace.GetFrames().FirstOrDefault(frame => frame.GetMethod().DeclaringType.FullName == typeof(T).FullName);
string methodName = string.Empty;
if (lastFrame != null)
methodName = lastFrame.GetMethod().Name;
return methodName;
}
Short Answer:
You can't.
Long Answer:
If you really need to do that, you will need to perform logging code in all the methods you want to track.
You can create a global variable (ugh) to store a MethodInfo with the last called method, and inside every method, set it to MethodBase.GetCurrentMethod(). Then whenever you want, you can examine that variable to see which method set it last.
In your case, you probably are trying to determine which method the exception was thrown in. You are looking at TargetSite, which returns the lowest method in the hierarchy, whereas you seem to want the one immediately below the current method. If simply examining Exception.StackTrace doesn't provide enough information, you might be able to parse out information from StackTrace and use reflection to get a MethodInfo. Usually, the StackTrace is good enough.
You may also be able to throw a new exception in the top-level method, so you can get the TargetSite from the new one.
Summary:
If Exception.StackTrace doesn't provide enough information, then you will either have to:
Perform logging code in each method you want to check for.
Parse out what information you can get from the Exception.
Change the exception throwing scheme to throw a new exception with InnerException set to the original exception.
I don't know why you want to do this.. because this is expected behaviour. The site of the exception is what you're being shown.. within the int.Parse() calls.
That being said.. if you really want to do this, you need to wrap a try.. catch in CheckValue, and re-throw the exception from there, but in a way that breaks the call stack.. like so:
public int CheckValue(bool sender) {
try {
var qwe = int.Parse("qwe"); // invoke an exception
return 0;
}
catch (Exception ex) {
throw ex; // this breaks the call stack and re-throws the exception from here..
}
}
Then, ex.TargetSite.Name == "CheckValue". I'm still not sure why you'd want to do this.. as a stack trace will actually show you where it all unwinds from after failure.
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 :)
Hi I wanted to ask because I'm not sure if is it propriete using of Exception:
public int Method(int a, int b) {
if(a<b) throw new ArgumentException("the first argument cannot be less than the second");
//do stuff...
}
can I throw Exception after if statement? or should I always use try - catch when it goes with the exceptions?
That is perfectly valid. That is exactly what exceptions are used for, to check for "Exceptions" in your logic, things that weren't suppose to be.
The idea behind catching an exception is that when you pass data somewhere and process it, you might not always know if the result will be valid, that is when you want to catch.
Regarding your method, you don't want to catch inside Method but infact when you call it, here's an example:
try
{
var a = 10;
var b = 100;
var result = Method(a, b);
}
catch(ArgumentException ex)
{
// Report this back to the user interface in a nice way
}
In the above case, a is less than b so you can except to get an exception here, and you can handle it accordingly.
In this case, you don't want to catch the exception. You're throwing it to alert the caller that they've made a mistake in the way they called your method. Catching it yourself would prevent that from happening. So yes, your code looks fine.
That's perfectly fine. You're throwing the exception, not catching/handling it, so you wouldn't need a try/catch block for it.
This is perfectly valid, you can use the same construct even with the constructors.
But What you should not do is
public int Method(int a, int b)
{
try
{
if (a < b)
throw new ArgumentException("the first argument cannot be less than the second");
}
catch (Exception)
{
}
return 0;
}
You've got the right idea. You could use your code like this:
void MyMainMethod()
{
// ... oh, let's call my Method with some arguments
// I'm not sure if it'll work, so best to wrap it in a try catch
try
{
Method(-100, 500);
}
catch (ArgumentException ex)
{
Console.WriteLine(ex.Message);
}
}
public int Method(int a, int b)
{
if (a < b) throw new ArgumentException("the first argument cannot be less than the second");
//do stuff ... and return
}
It might help to look through MSDN's Handling and Throwing Exceptions and Best Practices for Handling Exceptions
What you've done here is perfectly Ok.
A common pattern for arg checks is to wrap the check/throw code in a static "Contract" class ensuring you have a consistent approach to exception management when validating input arguments.
Slightly off topic but if using .NET 4.0 you can also look at the new Code Contracts feature for validation of method input and output.
All above answers are correct but I like to mention one additional point here which I did not see mentioned in any of the answers. The reason why you should throw an exception and not return an integer e.g. 0 or -1 for signalling that an error occurred, is that the returned integer can be mistakenly treated/assumed as a valid result of your method. It is an integer anyway, and your method, after performing its internal logic returns an integer. So the caller of this method can mistakenly treat any returned integer as a valid result, which can lead to bugs down the line. In that case, throwing an exception makes perfect sense.