This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
I have this code:
private void btnNext_Click(object sender, RoutedEventArgs e){
try
{
// Lots of codes in here
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message + Environment.NewLine + ex.StackTrace.ToString())
}
finally
{}
}
It is catching an exception but not telling me where the exception is occurring inside the code. The only thing I'm getting is this.
Object reference not set to an instance of an object
at ProjectPath.btnNext_Click(Object sender, RoutedEventArgs e)
The release code works fine on a lot a machines, but on few machines, it throws this exception. I just can't figure out where on the code the exception is occurring while running on those machines. Is there a way to find the exact line where the exception is occurring? ex.StackTrace didn't get the job done.
Any help will be appreciated.
You should ideally put separate try-catch blocks around areas where you think an exception would be thrown - instead of putting everything in the same one.
Otherwise, when you debug, it creates pdb files which - if they're present in the folder where the file is executing, you can get the line number.
That said, this error is pretty common, you have a null somewhere.
Added: Over here I'm assuming that for some reason you can't get the debugger to stop on exception, and/or can't trace it because you're deploying it to a third party or something.
To find the exact location -- the specific line in your source code -- it helps if you run the code in a debugger and set a breakpoint within the exception handler.
If you examine the data structure referenced as a parameter to the exception handler (ex in the example), you will find a data member named StackTrace. If the location is anywhere, it will be in here. Here, for example, is a string for an exception that I am working on right how:
at DOffice.BrMan.getLastReportRefreshed() in E:\\src\\BrMan.cs:line 5370
at DOffice.BrParms.lookupParmByParmName(String parmName) in E:\\src\\BrParms.cs:line 169
at DOffice.BrMan.populateAllFromTextFile(String workDirectory) in E:\\src\\BrMan.cs:line 3218
at DOffice.BrMan.setWorkPath(String pathOfCurrentDoc) in E:\\src\\BrMan.cs:line 1686
at DOffice.Form_Dash.InitWork(Object sender) in E:\\src\\Form_Dash.cs:line 1261
Related
Observations
I have an application which I have been told was running for several years with no issues, but has recently started crashing with a strange error. The code itself is fairly simple:
private void fileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
{
//Make sure it's not a folder that was modified
if (!Directory.Exists(e.FullPath))
{
var creationTime = File.GetCreationTime(e.FullPath);
// Rest of the code here...
However, the call to GetCreationTime, occasionally raises an exception, producing the following call stack:
System.IO.IOException: There are no more files.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.GetCreationTimeUtc(String path)
at MyClass.fileSystemWatcher_Changed(Object sender, FileSystemEventArgs e)
at ...
Now, I have scrubbed the MSDN documentation on GetCreationTime as well as examined the code closely using ILSpy, and have reached the following conclusions:
The System.IO.File.GetCreationTime method is an advanced wrapper to the equivalent set of Win API calls, including GetFileAttributesEx and FindFirstFile. I do not believe any of these calls should be returning error 18. In fact, the .NET implementation has a specific set of hard-coded errors it is expecting (2, 3, and 21), and in most cases will just eat the exception and return DateTime.MinValue instead.
Questions
What could be causing this exception, and what are the the best corrective actions to the code to avoid or prevent it? (Right now, I have added try catch around the block to just log the event and ignore.)
Could this be a Windows OS issue (similar to this old KB article)?
Your code is checking whether a path is not a directory. A false response doesn't mean that the path points to a file, it can also mean that there is nothing with this name.
Use File.Exists instead:
if (FileExists(e.FullPath))
{
var creationTime = File.GetCreationTime(e.FullPath);
I have developed a project which uses an external dll as FTPServer, I have created the FTP Server on my project like this:
private ClsFTPServer _ClsFTPServer;
_ClsFTPServer = new ClsFTPServer(FTPUserName, FTPPassword, FTPPath);
The Code above creates an instance of FTP server class, the class starts the FTPserver on it's constructor, it works fine independently as a module while the clients send their request correctly, but when an incorrect request comes to FTP server it throws an exception and cause my application to crash.
How can I handle the exception thrown by the external dll to prevent my application from crashing?
I recently answered a similar (ish) question which may prove useful -
Catch completely unexpected error
EDIT. I have to agree with Hans' comment above - might be an idea to find another FTP server.
Just for completeness, here's the appdomain/thread exception setup from - http://msdn.microsoft.com/en-GB/library/system.windows.forms.application.threadexception.aspx
Application.ThreadException += new ThreadExceptionEventHandler (ErrorHandlerForm.Form1_UIThreadException);
// Set the unhandled exception mode to force all Windows Forms errors to go through
// our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
In case of using external unmanaged\unsafe code, .NET (above .net 4) by default cannot handle Memory Access Violation exceptions that happens inside of dll code.
in order to catch these kind of exceptions, there is three things to do. I did them and it worked for me:
Add these Attributes to the method that exception occurred inside of it :
(the method that calls the method of the unmanaged code.)
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
Add this tag to App.Config file below runtime tag :
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true"/>
<!-- other tags -->
</runtime>
Catch these kind of exception by using System.AccessViolationException exception type :
try{
//Method call that cause Memory Access violation Exeption
}
catch (System.AccessViolationException exception)
{
//Handle the exception here
}
What i said is just the cure for these type of exception. for more information about this exception's ego and how this approach works, see System.AccessViolationException
You've probably already tried this, but just in case, have you tried wrapping it in a try catch?
try
{
_ClsFTPServer = new ClsFTPServer(FTPUserName, FTPPassword, FTPPath);
...
}
catch(Exception e)
{
...
}
By putting a try...catch block around every call into the object and its methods.
Something like:
try
{
// use the DLL in some way
}
catch (Exception e)
{
// Handle the exception, maybe display a warning, log an event, etc.)
}
Also note that while running under Visual Studio, if you go to the "Debug" menu and select "Exceptions..." it will allow the debugger to break on ALL exceptions if you start your program under the debugger, and not just unhandled exceptions. Just click the 'Thrown' checkbox next to "Common Language Runtime Exceptions".
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 Windows Console application built in Visual Studio 2010 and it keeps crashing but the error is not caught by the visual studio debugging tool nor by try/catch statements in my code.
I have managed to locate the WER file on my system and would like to be able to understand the contents of the file so I can pinpoint exactally what is causing the unhandled exception.
I would be greatful if anyone can offer some idea on how I can use the following information to locate the process causing me this problem and also what the exception may be...
The information from the WER file is:
Version=1
EventType=APPCRASH
EventTime=129973086237604286
ReportType=2
Consent=1
ReportIdentifier=91331e8b-2dc8-11e2-977b-080027f7e5bb
IntegratorReportIdentifier=91331e8a-2dc8-11e2-977b-080027f7e5bb
WOW64=1
Response.type=4
Sig[0].Name=Application Name
Sig[0].Value=SAGE_TESTING.vshost.exe
Sig[1].Name=Application Version
Sig[1].Value=10.0.30319.1
Sig[2].Name=Application Timestamp
Sig[2].Value=4ba2084b
Sig[3].Name=Fault Module Name
Sig[3].Value=ntdll.dll
Sig[4].Name=Fault Module Version
Sig[4].Value=6.1.7600.16385
Sig[5].Name=Fault Module Timestamp
Sig[5].Value=4a5bdb3b
Sig[6].Name=Exception Code
Sig[6].Value=c015000f
Sig[7].Name=Exception Offset
Sig[7].Value=000845bb
DynamicSig[1].Name=OS Version
DynamicSig[1].Value=6.1.7600.2.0.0.272.7
DynamicSig[2].Name=Locale ID
DynamicSig[2].Value=2057
DynamicSig[22].Name=Additional Information 1
DynamicSig[22].Value=0a9e
DynamicSig[23].Name=Additional Information 2
DynamicSig[23].Value=0a9e372d3b4ad19135b953a78882e789
DynamicSig[24].Name=Additional Information 3
DynamicSig[24].Value=0a9e
DynamicSig[25].Name=Additional Information 4
DynamicSig[25].Value=0a9e372d3b4ad19135b953a78882e789
Here is the section of code I believe to be causing the exception to be thrown:
//Data from the project linked to the split data
if (oSplitData.Project != null)
{
oProject = oSplitData.Project as SageDataObject190.Project;
oBasicDetail.ProjectID = oProject.ProjectID;
oBasicDetail.ProjectReference = oProject.Reference.ToString();
}
else
{
oBasicDetail.ProjectID = -1;
oBasicDetail.ProjectReference = "NO_PROJECT";
}
To add to all the above I seem to have found that there is a general exception that is being thrown but it doesn't help me out much - if anyone can put some light on this it would be great:
Unhandled exception at 0x78bc7361 in SAGE_TESTING.exe: 0xC0000005: Access violation reading location 0xfeeefeee.
If your program is multi-threaded and the exception is thrown in one of the spawned threads, the Exception may not be caught depending on how you do exception handling in your program.
You can add a catch-all exception handler like this:
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
// Your code here
}
static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine(e.ExceptionObject.ToString());
Environment.Exit(1);
}
}
UPDATE
Based on the code you posted, here are some things to look at
Put a try/catch block around the code you posted.
Are you sure that oSplitData is not null?
In the following line, oProject will be null if oSplitData.Project is not of type SageDataObject190.Project. Test for null.
oProject = oSplitData.Project as SageDataObject190.Project;
You are probably dealing with so-called corrupted state exceptions. These exceptions corrupt the process in a way so it is usually more safe to kill the process since it is very difficult to impossible to recover from such an error, even if it would be only for running a short catch-clause. Examples are StackOverflowExceptions, OutOfMemoryExceptions or AccessViolationExceptions.
There is an extensive and generally interesting explanation on corrupted state exceptions in this article.
What is helpful on getting a hand on such exceptions is to use DebugDiag. With this tool from Microsoft (download on this page) you can define a crash rule which generates a crashdump for your failed process. You can easily open these dump files in Visual Studio, where you may find the source of the exception that lead to the failure. This is not guaranteed but it often helped me in the past to nail down some nasty errors.
Are you invoking non-managed C++ or other code?
I'd try something like
static void Main()
{
try
{
DoSomethingUseful() ;
}
catch ( Exception e )
{
// managed exceptions caught here
}
catch
{
// non-managed C++ or other code can throw non-exception objects
// they are caught here.
}
return ;
}
See Will CLR handle both CLS-Complaint and non-CLS complaint exceptions?
Also C++ try, catch and throw statements at msdn: http://msdn.microsoft.com/en-us/library/6dekhbbc(v=vs.100).aspx
And MSIL opcode throw (0x7A) allows the throwing any object reference. C#, however, does not allow it.
But it looks like they improved things with .Net 2.0 and started wrapping oddball stuff in an RuntimeWrappedException.
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 ;)