This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
I am trying to a catch nullreference exception but I want to know the exact location (at which point or line I am getting that exception). I have one class named Employee and it has two properties: _Id and _Name.
static void Main(string[] args)
{
Employee empobj = new Employee();
try
{
empobj = null;
//empobj._Id = empobj._Id.ToString();
Console.WriteLine(empobj._Id);
Console.WriteLine(empobj._Name);
Console.ReadLine();
}
catch (NullReferenceException e)
{
Console.WriteLine("Exception caught: {0}", e.InnerException);
Console.ReadLine();
}
}
In visual studio go to Debug->Exceptions menu.
Then select "Common Language Runtime Exceptions", Check the Thrown checkbox. This will break the execution when exception is thrown. You can find the breaked line is where exceptio is thrown.
In case of NullReferenceException you won't get much help about stacktrace, but this way you can get the cause easily.
Look at the stack trace and it will have a break down of the execution tree, stating line numbers along with function names and so on. You can do this by debugging, outputting your exception stack trace to some medium, or by removing the try/catch and letting the exception halt execution of your application.
The key would be, though, to work around the exception so that it doesn't happen, if it's not an exceptional circumstance (i.e. if you expect that this is a scenario that could very well happen); so if your application can check, such as
if (thing != null) {
var id = thing.Id;
if (id != null) {
var idText = id.ToString();
// and so on
}
} else {
}
Where in the else, you either continue a different route, let the user retry or whatever.
If it is a truly exceptional circumstance (i.e. things should never be null) and the app can't do anything if it is, then let the exception happen, it breaks the application.
Stack trace is the way to go, but the exception is coming from the following lines:
Console.WriteLine(empobj._Id);
Console.WriteLine(empobj._Name);
You are setting the employee object to null
empobj = null;
and then trying to access member variables from that class, which will no longer have values for these variables
Related
I'm going to catch all unhandled exceptions in my Winforms app. Here is the shortened code:
[STAThread]
static void Main()
{
if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe"))
{
Application.ThreadException += new ThreadExceptionEventHandler(MyCommonExceptionHandlingMethod);
}
Application.Run(new frmLogin());
}
private static void MyCommonExceptionHandlingMethod(object sender, ThreadExceptionEventArgs t)
{
Exception ex = t.Exception;
StackTrace trace = new StackTrace(ex, true);
var db = new MyDataContext();
Error error = new Error();
error.FormName = trace.GetFrame(0).GetMethod().ReflectedType.FullName;
error.LineNumber = trace.GetFrame(0).GetFileLineNumber();
error.ColumnNumber = trace.GetFrame(0).GetFileColumnNumber();
error.Message = ex.Message;
db.Errors.InsertOnSubmit(error);
db.SubmitChanges();
if (new frmError(ex).ShowDialog() != DialogResult.Yes)
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
The issue is that sometimes FormName, LineNumber and ColumnNumber are not correctly returned. Here is the result that I sometimes get:
--FormName-- --Line/Column-- --Message--
System.Linq.Enumerable 0 0 Sequence contains no matching element
System.RuntimeMethodHandle 0 0 Exception has been thrown by the target of an invocation.
System.Number 0 0 Input string was not in a correct format.
System.Number 0 0 Input string was not in a correct format.
System.ThrowHelper 0 0 Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
As you can see, LineNumbers and ColumnNumbers are 0. FormName is System.Linq.Enumerable ...
How can I solve the problem?
How can I solve the problem?
When no .pdb is present for a given module, the stack trace information will necessarily not be able to include file names, line, or column numbers.
To get them, you need to make sure you have the .NET .pdb available and loaded. There are a number of resources available which describe how to do this. See Cannot step into .NET framework source code, for example, or Advanced .NET Debugging - PDBs and Symbol Stores. You can use your favorite web search engine to find additional resources.
I'll note also that you are describing the type name as the "FormName", which is incorrect. It's only the form name when the exception was in fact thrown by your form. Unhandled exceptions are always bugs, and as such are very often thrown by framework or other library code, and the types won't be forms.
I will also mention that catching all exceptions is useful only for diagnosing bugs. This should not be used as an attempt to improve general reliability of a program (except to the extent that better diagnosis can allow you to fix bugs). When an unhandled exception occurs, you should log it and then kill the process. Allowing a process to continue executing after an unhandled exception occurs is dangerous for your data, and can lead to complacency with respect to bug-fixing.
I have an ASP.net website with C#. Current framework is 4.5
I have a global unexpected error catching function.
It is located at global.asax
Here how i catch
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
if (Server.GetLastError() != null)
if (Server.GetLastError().GetBaseException() != null)
{
Exception objErr = Server.GetLastError().GetBaseException();
ErrorLogger.LogError(Request.Url.ToString(), objErr.Message.ToString(), objErr.StackTrace.ToString());
if (objErr.Message.IndexOf("does not exist") != -1)
{
Response.RedirectPermanent("Error404.aspx");
}
}
}
Now it catches errors and many times there are plenty of information to debug the error. However there is 1 error that i can not get enough information.
It is Object reference not set to an instance of an object.
It doesn't give any information about which object it is. Are there any way to get more information about it ?
Here a typical error
Object reference not set to an instance of an object.
at gamepage.Page_Load(Object sender, EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Thank you very much for answers.
A NullReferenceException does not carry information about the variable which is null, no.
It doesn't give any information about which object it is.
That's just it... it isn't an object. It's a reference to where an object is expected, but there's no object there. null is literally the absence of information.
The way to handle a NullReferenceException is to carefully craft your code so that either:
It doesn't happen, or
It happens in a potentially expected way, and you check for it and either throw a custom informative exception (which can still be a NullReferenceException with simply a custom message) or in some way log/persist the information and meaningfully continue execution of the application.
Since no code or developer is perfect, it's fully expected that from time to time one will slip through the checks and balances. This is ok. It should be easy to identify which object is null in this case. The stack trace should point to a specific method (perhaps even a specific line of code, depending on what information is available to the runtime) and there shouldn't be a whole lot of potential NullReferenceExceptions there. If there are, the method is sloppy and should be cleaned up anyway.
When it happens, identify the object which was null by debugging and investigation, and update the code to handle the potential null case for that object.
One thing you could do to help with tracking down the problem would be to find the method that has errored, and possibly even the line of code within that by performing a runtime stacktrace, something like:
var st = new StackTrace();
var errorInfo = String.Join("...", st.GetFrames().Select(x =>
{
var m = x.GetMethod();
var t = m.DeclaringType;
return String.Format("{0}.{1} # {2}:{3}:{4}", t == null ? "" : t.Name, m.Name, x.GetFileName(), x.GetFileLineNumber(), x.GetFileColumnNumber());
});
that will allow you to find the code and fix it. I've not used such an approach in a global error trap such as the Application_Error event handler you are using, but I have used this approach to see where calls are coming from in other scenarios successfully, often to track down event handlers that are subscribed to an event.
Use try..catch when you use any object and throw error with inner exception and stacks trace so you can log that error and get more information about specific error.
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
I need to rethrow an Exception that was caught and stored elsewhere without losing the stack trace information about when the Exception was first caught/stored. My code looks something like this:
public void Test()
{
int someParameter = 12;
ExecuteSomeAsyncMethod(someParameter, CallbackMethod);
}
public void CallbackMethod(object result, Exception error)
{
//Check for exceptions that were previously caught and passed to us
if(error != null)
//Throwing like this will lose the stack trace already in Exception
//We'd like to be able to rethrow it without overwriting the stack trace
throw error;
//Success case: Process 'result'...etc...
}
I've seen solutions to this problem that use reflection (for example here and here) or use Serialization (for example here) but none of those will work for me in Silverlight (private reflection is not allowed and the classes/methods used in the serialization approach don't exist in Silverlight).
Is there any way to preserve the stack trace that works in Silverlight?
Throw a new exception with the exception as inner exception:
throw new ApplcationException("Error message", error);
The inner exception will keep it's stack trace.
You can either use
catch(Exeption)
{
throw;
}
or
catch(Exception e)
{
throw new Exception(e);
}
Both will keep the stack trace. The first solution seems not to be possible in your example, but the second should work.
Of cause in your case you would throw the parameter error instead of e.
In dotNet a line throws an exception and is caught, how can I figure out which line in which file threw the exception? Seems relatively straightforward, but I can't figure it out...
You can only do it if you have debug symbols available.
catch(Exception ex) {
// check the ex.StackTrace property
}
If you want to debug such a situation in VS, you'd better just check Thrown checkbox for Common Language Runtime Exceptions in Exceptions dialog located in Debug menu. The debugger will break as soon as the exception is thrown, even if it's in a try block.
Personally, I just log the exception's ToString() return value. The whole stack trace is included. It's one line of code ... dead simple.
You could use the StackFrame Class:
try
{
...
...
}
catch(...)
{
StackFrame sf = new StackFrame(true);
int lineNumber = sf.GetFileLineNumber();
int colNumber = sf.GetFileColumnNumber();
string fileName = sf.GetFileName();
string methodName = sf.GetMethod().Name;
}
Well, in .NET you have whats called a FirstChanceException. These essentially are thrown before an exception is handled. There are two ways of looking at the issue that you're presenting here. One is from a debugging angle. If debugging you can just set your debugger to catch thrown exceptions from the Debug/Exceptions window. This is easier in an interactive context. IF you need to record this information from within a non-interactive context then I would do something similar to what CMS is talking about...
try
{
...
}
catch(Exception ex)
{
System.Diagnostics.StackTrace stackTrace = new System.Diagnostics.StackTrace(ex);
System.Diagnostics.StackFrame firstFrame = stackTrace.GetFrame[0];
Console.WriteLine(firstFrame.GetFileLineNumber);
...
}
The only difference here is that we get the entire Stack Trace, then go to the first frame, which is where the exception was originally thrown.