C# .Net 4.6.1
I am using a 3rd party library. When iterating through its object, my program blows up because the property i'm accessing from the library has thrown an exception.
So when my program gets to this line of code, the exception is thrown:
case CellType.Formula:
{
cNew.CellFormula = "IFERROR(FF3 / EY3,\"\")";
cNew.SetCellFormula(cOld.CellFormula); //this is where it blows up
break;
}
When debugging the code, I can see the exception has been thrown. The image above shows this. So, I know something has gone wrong in the library property and what I want to do is capture this error BEFORE hitting the line of code using the property and keep going along with the application.
Is there a way to check an object for exceptions and tell my code to skip over it or do whatever? For example:
if (cOld.CellFormula == Exception){
// do something
}
Thanks
On the breaking line
cNew.SetCellFormula(cOld.CellFormula);
You can put a try catch around it, like so
try
{
cNew.SetCellFormula(cOld.CellFormula);
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
this will display a message box with the error text in it
If you are running this as a console application replace
MessageBox.Show(e.Message);
With
Console.WriteLine(e.Message);
That will write the message to the screen (remember to take it out in production!)
Related
I have some code that currently looks somewhat like this:
public void MainFunction()
{
try
{
SomeProblemFunction();
}
catch
{
AllFineFunction();
}
}
private void SomeProblemFunction() { ... }
private void AllFineFunction() { ... }
As you can see, I'm currently wrapping the call to SomeProblemFunction around a try statement because that function could fail (it relies on an outside web service call).
My question is this: should the try statement be a) outside the problem function (like I have it now) or b) inside the problem function?
Thanks.
Typically you want to allow your exceptions propagate up to your application boundaries. You're only going to want to do one of a few things with your exception:
Wrap it
Replace it
Let it propagate
Update
From your question it seems that you are looking for a fault tolerant solution for your web service calls. This is a more complex problem than simply "where do I put my try-catch?" You would still place your exception handling at the application boundary, but there you would implement your fault tolerance strategy. This would need to have many considerations, including asynchronously calling your web service, number of retry attempts, etc. I would suggest doing a search for web service fault tolerance.
What you have is correct; see the MSDN example:
public class ThrowTestB
{
static void Main()
{
try
{
// TryCast produces an unhandled exception.
TryCast();
}
catch (Exception ex)
{
// Catch the exception that is unhandled in TryCast.
Console.WriteLine
("Catching the {0} exception triggers the finally block.",
ex.GetType());
// Restore the original unhandled exception. You might not
// know what exception to expect, or how to handle it, so pass
// it on.
throw;
}
}
public static void TryCast()
{
int i = 123;
string s = "Some string";
object obj = s;
try
{
// Invalid conversion; obj contains a string, not a numeric type.
i = (int)obj;
// The following statement is not run.
Console.WriteLine("WriteLine at the end of the try block.");
}
finally
{
// Report that the finally block is run, and show that the value of
// i has not been changed.
Console.WriteLine("\nIn the finally block in TryCast, i = {0}.\n", i);
}
}
// Output:
// In the finally block in TryCast, i = 123.
// Catching the System.InvalidCastException exception triggers the finally block.
// Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
}
As a rule of thumb I try and build code that focuses try catches to the exact spot the problem may occur.
That said both of your solutions are correct.
If it were my code I would do this
public void MainFunction()
{
try
{
SomeProblemFunction();
}
catch(Exception e)
{
Messagebox.Show(e.Message);
}
}
private void SomeProblemFunction() {
try{
web call
}
catch{
throw a specific exception related to this spot
}
}
private void AllFineFunction() { ... }
With this method you can easily create applications that handle a slew of very accurate exceptions
A fine question, I think. I'll attempt an answer.
If you want to recover within SomeProblemFunction, then it would make perfect sense to move the try...catch inside of that method. If, however, you are comfortable saying that if anything fails in SomeProblemFunction, then the whole thing is a failure, then keep it as you have it now and recover in (or throw from) MainFunction.
Thanks to the comment below, I'm adding some clarity. Depending on the specific exception that is being thrown within SomeProblemFunction, you may not have the ability to recover within that method. If you have a mixture of recoverable and non-recoverable, then it would be prudent to have the try...catch in both places.
The most important thing is that you NEVER catch an exception from which you cannot recover without throwing it on after doing your thing. It's tempting to add big broad catches (catch (Exception)) to avoid your app crashing during development, but it is never worth it. If those things make it into your production code, you've introduced a problem-solving and debugging nightmare.
In my opinion, there is no straight answer for this. The try catch is used to handle the exceptions that may occur. If your exception handling code is going in the main function then you should have the try catch in the main function. If your exception handling code in the problem function then you should add it to the problem function.
My preference though is to put it in both functions. If you put the try catch in the problem function, you can throw the exception and catch it in the main function. This always appear to other developers that the exception was thought of in that function and not missed handling it by mistake.
This depends on how severe this web service call failure would be.
Is it a failure that would prevent further processing of your code to run? If so, have no try/catch here, allowing it to propagate up to the guy who needs to know that this web service call failed. Optionally, you could still catch and throw a new exception with some more meaningful Exception type/ details.
Do you simply just want to re-try the web service call again if it doesn't work? IF so, then you have the try in the correct place; you just need to add a loop.
Is it not a big deal if this web service call fails? e.g. - will the rest of your code work OK? (I've found this to be uncommon). If so, leave the try/catch where it is, and log the error somewhere so that you're alerted.
I am using a library that doesn't seem to document the exceptions. This library is used to communicate with a product the company makes. I want to be able to differentiate between the exceptions that get thrown but I don't know the names of the exceptions (for example between a communication timeout or under-voltage condition).
All of their examples only use catch(Exception ex). How can can I find what I need to use to catch the individual errors? When I do ex.toString() I get something like this:
System.Exception: Timeout
at CMLCOMLib.EcatObj.Initialize()
at copley_cmo_test.MainWindow.btnConnect_Click(Object sender, RoutedEventArgs e)
in c:\Users\adam.siembida\Desktop\copley_cmo_test\copley_cmo_test\MainWindow.xaml.cs:line 41
This:
System.Exception: Timeout
shows that they're just throwing a bare System.Exception, e.g.
if (weHaveNoApiDesignSkills)
{
throw new Exception("Timeout");
}
It's possible that there are some exceptions which are better designed, but the one you've shown isn't promising :(
Unfortunately unless you start using the message in the exception to differentiate between them (which is almost always a bad idea) you're stuck. It may be worth asking the authors of the library to see if they can improve matters for a future release.
Catch it with a catch-all construct such as catch(Exception ex), then examine the Type returned by ex.GetType(). If it's equal to typeof(Exception), it means that they aren't throwing anything more specific than Exception.
By the way, if you're stopped when the exception has been caught (ie, in a catch block), if you enter $exception in the watch window, you will see the entire exception.
When the API in library which you are using is not documented properly , you should catch the base exception and log it not only by the message instead whole exception by converting the exception to string . Eg.
try
{
//api call which throws exception.
}
catch(Exception ex)
{
//log ex.ToString();
}
use a decompiler for example:
http://www.jetbrains.com/decompiler/
in .net there's no explicit exception declaration like in java so as i see it it's the only way.
I'm having problems working with EntityFramework. While below peace of code works fine on my PC, when it's transported to a VPS (with everything properly preinstalled), it gives me a Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object, but the message box that is supposed to catch this does not show up. Any suggestions?
Thank you in advance.
var cc = new CopierContext();
try
{
MessageBox.Show(cc.Database.Connection.ConnectionString.ToString());
var matchingProviders2 = cc.Providers.Where(prov => prov.Login == "batman");
}
catch (Exception e)
{
MessageBox.Show(e.InnerException.Message);
}
Update:
I finally got to the core of the problem. The reason is: I've had .NET 4 on VPS, while application was developed using .NET 4.5. Installing the latter one removed all problems. Thank you for all your help.
I don't know how you are running it on your VPS, but if it is not launched under the interactive user account, your message boxes will not show up.
Well from the docs on the Exception.InnerException Property
The InnerException property returns the same value as was passed into
the constructor, or a null reference
Since you're catching any old exception catch (Exception e) its quite possible that the exception that's being thrown isn't the exception you were expecting and doesn't have a InnerException. This means your catch block may be raising an exception.
There are several actions you could take.
Do not catch System.Exception exception in anything but a top level exception handler. Only catch exceptions you know what to do with. Which leads to...
Set up a top level exception handler
Finally when logging or displaying exception messages at least make sure you have an inner exception before you try and use it.
MessageBox.Show( (e.InnerException != null ? e.InnerException : e).Message );
Don't use a MessageBox as it is a service; log them to disk instead such that you can recall them, or perhaps automatically mail them to you such that you are up to date on problems occuring.
You will also want to add e.InnerException.StackTrace to the log.
My bet is that you did not configure something (or did not configure it correctly) and cc.Database.Connection.ConnectionString is null. Calling .ToString() causes the NullReferenceException. That's why you don't see the message box. As other people said - using MessageBox for this kind of debugging is not a good idea. In the catch you should print not message but e.ToString() it will show the stack trace that should point to the place where the problem is.
This method below is called when you click save all button.
I want to ask you is there any way to skip the error under the code shown below.
Why I ask this: Some times the pDenemeProxy.dll does not exist in the folder of the code.
Morever it is a windows form application. Has the pDenemeProxy.dll in the references. And the fDenemeProxy facade of pDenemeProxy.dll is only initialized if the mDesTemp not null.
Thank you!
private bool SaveAll()
{
...
..
..
if (this.mDesTemp != null)
{
fDenemeProxy dnm = new fDenemeProxy();
dnm.SaveThisCustomer(1234,"D",true);
}
...
..
return;
}
Error: System.IO.FileNotFoundException: 'pDenemeProxy, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
note: .net 2.0 and c#
note: Some people advice to put try catch block but it did not work. I have seen during the debug sessions on VS 2008 that when mDesTemp is null we see again the error declared above.
In some line in your code you are using a method which throws an Exception of type System.IO.FileNotFoundException if the conditions for this erroneous situation are true (i.e. you are trying to access a file which is not possible for some reason).
That's the intended and correct behavior what you are experiencing. Whenever you are getting this error message the error has already been happened and now it's up to you to deal with this new situation. That is what Exception-Handling is all about.
To deal with an error that was caused by an exception (informally speaking) you would have to catch a exception that has been thrown before (formally speaking).
To do that you have to enclose the portion of code (the actual method call that inheres the throwing of the exception) with a so-called try-catch block like this:
private bool SaveAll()
{
...
..
..
if (this.mDesTemp != null)
{
try {
fDenemeProxy dnm = new fDenemeProxy();
dnm.SaveThisCustomer(1234,"D",true);
} catch (FileNotFoundException e) {
// deal with the new situation !
}
}
...
..
return;
}
The meaning of that is very simple and intuitive:
Inside the try-block you are 'securing' a piece of code that is capable of throwing an exception for the case it is doing so. This try - block is then followed by an arbitrary number of catch-block - one for each exception that could be thrown by the secured code.
If you have set up this try-catch block correctly you have achieved that whenever your (secured) code throws an exception the execution flow of your program doesn't end (i.e. you program doesn't crash) but it goes to the aproprirate catch-block where you can do anything to deal with error you have just experienced.
Furthermore if you would look on the internet you will find lots of information on that since exception-handling is a very important concept of programming but what I've tried to explain here is the basic concept which you should try to understand first - it won't get more difficult ;)
I have a c# program which throws a NullReferenceException(). When I start this on my Vista machine, it gives the familiar screen "Foo has stopped working". I can easily click on 'details' to see what went wrong. On one XP machine there's no warning at all: the program just quits, and on another XP I get the "Foo has encountered a problem..." message. Is there a way I can change this (XP's) setting?
Furthermore, I would like to have this error message written to a log file, so I can see what went wrong if somebody else uses my program. Is there a way I can send the uncaught exceptions to a file?
edit: I want this for my entire project, not just for a critical section. I didn't think it is recommended practice to wrap the entire program in a big try...catch, or is it?
Take a look at : UnhandledException and ThreadException.
You may log the errors in a file, or use Windows logging facilities.
You may also try this and this, it should point you in the direction you want to go. It's a post about the exact same problem you are trying to solve.
If you're targeting WPF, you can use the DispatcherUnhandledException to catch any exception that you don't handle in code. Otherwise, make sure to catch any foreseeable exception with try-catch blocks.
Either in DispatcherUnhandledException's delegate or in the catch section of a try-catch block, you can then call a function that writes the error message to a log file.
Add try catch blocks around all components that you think will fail and handle these by streaming the error data to your log file
See this link:
http://blogs.msdn.com/csharpfaq/archive/2006/03/27/562555.aspx
This will get you up and running.
Use:
try
{
// Your code here
}
catch (Exception ex)
{
// This will tell you the Exception
Console.WriteLine("Exception type: {0}", ex.GetType());
// or, if you use the example from the link above
LogMessageToFile(String.Format("Exception type: {0}", ex.GetType));
}
You could wrap up your code in a
try
{
// Your code
}
catch (Exception ex)
{
streamWriter.WriteLine("your custom exception text, stack trace:" + ex.StackTrace.ToString());
MessageBox.Show("Your custom exception text, Stack Trace:" + ex.StackTrace.ToString());
}
and handle the feedback yourself with a stream writer object pointing to a log file of your chosing.
If its a winforms app you could include a message box or custom dialogue informing the user of what happened as shown above.