I have log4net successfully setup for my C# application. Everything works fine, except when I do this:
catch (Exception ex)
{
if (log.IsErrorEnabled)
log.Error("test", ex);
}
All I get is the message "test", I do not get the exception at all. Then, when I do this:
catch (Exception ex)
{
if (log.IsErrorEnabled)
log.Error(ex);
}
I get the exception as desired, stack trace and everything. This works, but ideally I'd like to have both the message and the exception.
Why does the exact same code (no configuration changes) not work in the first example but it does in the second example? Am I reading the docs wrong for the Error() method?
The first overload you are using is the one that you want: Error(string, Exception). If the exception is actually written depends on your appender and / or the layout you choose. Here is explained how to disable printing of the stacktrace: https://stackoverflow.com/a/3660529/106567
I need to see your configuration in order to tell why the exception is not printed.
The code that "works" is not really what you should do: log.Error(ex) seems to do what you want since log4net treats the exception as the message object and simply calls toString() on it. Any appender / layout that specifically deals with exceptions would be unable to process the exception properly. The same happens if you use one of the ErrorFormat overloads (actually I never quite understood, why you cannot use a formatted string and an exception at the same time).
The solution was not relevant in the code I posted, but I was not fixing the flags correctly. The eventual solution was already found in this stack overflow post
Try
log.ErrorFormat("test: {0}", ex);
Related
Is it possible to throw a custom Exception from SSRS that I can catch in C#?
Something like:
try
{
result = ssrs.Render(
format,
null,
out extension,
out encoding,
out mimeType,
out warnings,
out streamIDs);
}
catch (CustomException ex)
{
// do something
}
catch (Exception ex)
{
}
I'd use it to not display the report in the client's system. I'd prefer to keep business logic in the report.
We wanted to throw an exception to not generate a report based on data. We tried a custom DLL to raise an exception. Unfortunately that did not work either.
What we did is raise an error with a specific string from a stored procedure and parse the Exception message in C# that worked pretty well. Not as nice as we'd have like though.
Throwing a custom exception type that you implement inside your application? I don't think that's possible.
But, looking at the rendering code using a disassembler, it does look like it attempts to wrap many of the Reporting Services rendering/viewing exceptions using a base exception class ReportViewerException. You could attempt to catch that exception type and that should handle many of the rendering issues.
Granted, you can still get things like a ArguementOutOfRangeException, which would not be wrapped in a ReportViewerException. So you may want to take that into consideration as well.
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.
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.
I read a lot about how bad catching base Exceptions is and I have to confess that I did it also:
try{
...
}
catch (Exception exception){
MessageBox.Show(exception.Message, "Error!");
MyLogger.Log(exception.Message);
}
Now I would like to do it right and have some questions about it:
Which exceptions should I catch (for example FileNotExists for file manipulation, but what for TableAdapter or ReportClass (CrystalReports))
Where can I see a list of exceptions, that an objects can throw (for example TableAdapter)
Where in Windows Forms Application can I set a static method, which will log any exception to a file for example
Any other suggestions?
Catch whichever exceptions you can reasonably handle. For example, if you're trying to open a file for writing, you should expect that maybe the file is marked read-only, so that would throw an exception. But in the same situation you wouldn't try to catch a null argument exception, because that would be due to programmer error.
They should be found in the function reference in MSDN (you'll have to look it up on each one). For user-defined functions, you'll have to go digging, unless there is additional documentation or summary commentary.
3, 4. Consider using a logging library for .NET
I have one thing to add. If you just want to log an exception without affecting program flow you can always do this:
try
{
...
}
catch (Exception exception)
{
MyLogger.Log(exception.Message);
throw;
}
That's up to you to decide which exceptions your application logic can reasonably expect to recover from.
Exceptions are thrown by method invocations, not objects. In Visual Studio, Intellisense explanations will tell you which exceptions are thrown by an object (provided that the XML documentation describes which exceptions a method throws.
Rather than use a static method, respond to the Application.ThreadException event. The link provided has examples.
MSDN
You can set an event for unhandled exceptions in application events file
(got a VB sample here but i hope you get the point)
Private Sub MyApplication_UnhandledException(ByVal sender As Object, ByVal e As Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs) Handles Me.UnhandledException
End Sub
You can find the application events in the options of you project.
You should only catch exceptions you can do something about, really.
That's the rule of thumb. I typically have a try/catch around my Program.Main just in case an exception bubbles right to the top and needs logging. You can also handle the CurrentDomain_UnhandledException event, in case exceptions are thrown in other threads than the UI thread (assuming you are multithreading).
In response to "4. Any other suggestions?":
In your example code, a message box is displayed before logging the exception. I would recommend logging the exception before displaying the message, just in case the user sees the error message, panics, and goes on vacation without clicking "OK". It's a minor thing, but message boxes block the program indefinitely and should be used with discretion!