I have a C# Console app that starts in 'static int Main(string[] args)', creates an instance of 'EventRecievedProcessor' class and then calls a method on the instance:
static int Main(string[] args)
{
try
{
EventRecievedProcessor proc = new EventRecievedProcessor
if (!proc.Processs())
{
Console.Write(Type + " processing failed. Please check logs for more information.");
Log.Error("Failed to process s");
return (int)RETURNCODES.INTERNALAPPERROR;
}
}
catch (Exception ex)
{
// This is where the System.NullReferenceException from GetLatestEventInfo is currently being caught
Console.WriteLine("Exception message: " + ex.Message);
Console.WriteLine("Exception stack trace: " + ex.StackTrace);
Log.Fatal("An exception has been thrown. Message: " + ex.Message, ex);
return (int)RETURNCODES.INTERNALAPPERROR;
}
}
The instance of 'EventRecievedProcessor' grabs a collection of records and does a foreach over it. It calls a static method (GetLatestEventInfo) on the 'Event' class for each record in the collection:
public class EventRecievedProcessor
{
public bool Processs()
{
List<Event> events = DAL.GetEvents;
foreach (Event e in events)
{
try
{
EventInfo lastEvent = Eventhistory.GetLatestEventInfo(e);
}
catch (Exception ex)
{
// Log exception and continue processing in foreach loop
// This is where I want to catch the NullReferenceException from GetLatestEventInfo
Log.DebugFormat("Error with eventid " + e.EventID);
Log.Error(ex);
}
}
return true;
}
}
When the follwoing method is called, a System.NullReferenceException is thrown:
public class EventHistory
{
public static EventInfo GetLatestEventInfo(int customerCode, string premiscode)
{
EventInfo info = new EventInfo();
// Do some work here...
// This is where the NullReferenceException is being generated.
return info;
}
}
When the NullReferenceException is thrown here, I would expect the catch block in the foreach loop to catch it, log it, and then return control to the foreach loop to continue processing. Instead, the exception is being caught in the top level 'Main' method, which means the app aborts and the remaining records are not processed.
I'm at loss as to how/why the exception bypasses the first catch block. Any ideas on what I'm doing wrong here?
Adding the stack trace:
System.NullReferenceException: Object reference not set to an instance of an object.
at EventProcessor.EventHistory.GetLatestEventInfo(Event e) in C:\Dev\release6.01.100\Events\EventProcessor\EventProcessor\EventHistory.cs:line 65
at EventProcessor.Processors.EventProcessor.Process() in C:\Dev\release6.01.100\Events\EventProcessor\EventProcessor\Processors\EventProcessor.cs:line 32
at EventProcessor.Program.Main(String[] args) in C:\Dev\release6.01.100\Events\EventProcessor\EventProcessor\Program.cs:line 132
Sorry if I've munched some of the names. This is work code, so I tried to change it up a little to avoid any privacy conflicts.
It doesn't bypass anything. Look closely at your stack trace.
Try using Console.WriteLine(ex.ToString());.
You'll see that the exception is not being thrown from where you thought it was.
This simply isn't the case and here's the proof:
class Program
{
static void Main()
{
// no need of try/catch here as exceptions won't propagate to here
Looper();
}
static void Looper()
{
int processedRecords = 0;
for (int i = 0; i < 10; i++)
{
try
{
Thrower(i);
processedRecords++;
}
catch (NullReferenceException ex)
{ }
}
// prints 5 as expected
Console.WriteLine("processed {0} records", processedRecords);
}
static void Thrower(int i)
{
if (i % 2 == 0)
{
throw new NullReferenceException();
}
}
}
Related
I got this weird exception:
Collection was modified; enumeration operation might not execute.
This is my code:
void WriteTask(DataTable dt, string outputFilePath, bool final)
{
if (final)
{
exiting = false;
dbWriteTime = 0;
}
while (!exiting)
{
if (TimeCurrent - dbWriteTime >= 10)
{
try
{
dbWriteTime = TimeCurrent;
dt.WriteXml(outputFilePath + "users.xml");
if (final)
exiting = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
Thread.Sleep(1000);
}
}
This is a task that every 10 seconds writes datatable to a file. I have searched this exception online, what I can find is that this exception occurs in a foreach loop if the collection has been changed. But I'm not using foreach.
I am catching an exception and processing it.
Somewhere up the call tree, I am doing the same.
Once I process my exception at the child level, I want to also go ahead and invoke the exception handler, wherever it is, somewhere up the call tree.
For that, I thought I would do run the throw again.
But instead of breaking somewhere up the call tree, it is breaking in the place where I am doing the throw and crashing, at this line:
throw new Exception("Cannot Write Header Row to Database " + Msg);
code:
public static void NewHeaderRow(string FILE_REV_NUMBER, DateTime FILE_CREATE_DATE, string EDC_DUNS_NUMBER, int RunId)
{
SqlConnection connection = null;
try
{
connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConn"].ToString());
connection.Open();
SqlCommand com;
com = new SqlCommand("dbo.INSERT_PPL_HEADER", connection);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.Add(new SqlParameter("#FILE_REV_NUMBER", FILE_REV_NUMBER));
com.Parameters.Add(new SqlParameter("#FILE_CREATE_DATE", FILE_CREATE_DATE));
com.Parameters.Add(new SqlParameter("#EDC_DUNS_NUMBER", EDC_DUNS_NUMBER));
com.Parameters.Add(new SqlParameter("#RunId", RunId));
if (com.Connection.State == ConnectionState.Closed) com.Connection.Open();
com.ExecuteNonQuery();
}
catch (Exception e)
{
string Msg;
Msg = "Encountered unexpected program issue. Please contact your program administator. Error details...";
Msg = Msg + System.Environment.NewLine;
Msg = Msg + System.Environment.NewLine;
Msg = Msg + e.ToString();
Msg = Msg + System.Environment.NewLine;
Msg = Msg + System.Environment.NewLine;
Msg = Msg + e.Message;
throw new Exception("Cannot Write Header Row to Database " + Msg);
}
finally
{
if (connection == null) { } else connection.Close();
}
}
Try just using the throw keyword, instead of building a new exception.
https://stackoverflow.com/a/2999314/5145250
To add additional information to the exception warp it in another exception object and pass the original exception as argument with new message to keep the original stack trace in inner exception.
throw new Exception("Cannot Write Header Row to Database " + Msg, e);
At some top level you should handle global exceptions to avoid crashing.
The way I was finally able to pin point the problem was to extremely simplify my code so as to be able to see the problem clearly. I just copied my solution to a new location, and gutted out all the non-essential stuff -- stuff I knew was not going to be important for the purposes of troubleshooting.... Very effective way of troubleshooting difficult problems that are hard to trace.... Here is what I ended up with (the simple code).
I was not catching general exception in the code that calls NewHeaderRow.
I was catching System.IO exception.
So, because code had nowhere to go, it crashed....
It is very hard for the eyes to catch this error and also difficult to trace.
private void button1_Click(object sender, EventArgs e)
{
LoadFile();
}
private static int ProcessHeaderRow(string line)
{
int LoadRunNumber = 0;
try
{
//some complex logic was here; error occurs here, so I throw an exception....
throw new Exception("An Error Occurs -- Process Header Row Try block");
}
catch (CustomExceptionNoMessage e)
{
throw new CustomExceptionNoMessage(e.Message);
}
catch (Exception e)
{
//Process the exception, then rethrow, for calling code to also process the exception....
//problem is here...XXXXXXXXXXXXXXXXXX
throw new Exception(e.Message); //crashes
}
return LoadRunNumber;
}
public static bool LoadFile()
{
int RunId = 0;
try
{
RunId = ProcessHeaderRow("10~~happy~007909427AC");
MessageBox.Show("Completed Upload to Cloud...");
}
catch (CustomExceptionNoMessage ce)
{
MessageBox.Show(ce.Message);
}
catch (System.IO.IOException e) //CHANGED THIS LINE, AND I AM UP AND RUNNING (Changed to Exception e)
{
MessageBox.Show(e.Message);
}
return true;
}
public class CustomExceptionNoMessage : Exception
{
public CustomExceptionNoMessage()
{
}
public CustomExceptionNoMessage(string message)
: base(message)
{
}
public CustomExceptionNoMessage(string message, Exception inner)
: base(message, inner)
{
}
}
private void button1_Click(object sender, EventArgs e)
{
LoadFile();
}
How is it possible that thrown TimeoutException object is null and it throws
Object reference not set to an instance of an object.
in following line:
writeToLog(e2.ToString());
Check out this code.
WebServiceRef.CallResponse callResponse = null;
try
{
callResponse = webServiceClient.Call(callRequest);
}
catch (TimeoutException e)
{
try
{
WebServiceRef.CallStatusResponse callStatusResponse = webServiceClient.CallStatus(callStatusRequest);
if (callStatusResponse.ResponseCode != 0)
{
throw new Exception("nok: " + callResponse.ResponseCode);
}
}
catch (TimeoutException e2)
{
writeToLog(e2.ToString());
}
}
This is my writeToLog method.
private static void writeToLog(String logMsg)
{
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"log.txt", true))
{
file.WriteLine(DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss ") + logMsg);
}
}
Stacktrace and message is this:
Object reference not set to an instance of an object.
at ...(...) in c:\...cs:line 82
at ...(...) in c:\...cs:line 193
Line 82 is point at
writeToLog(e2.ToString());
There is no way a null Exception instance can be thrown / caught.
Either something must be wrong with your debug symbols or you're not running the correct program. Try logging some test strings here and there to make sure the correct code is executed:
//...
catch (TimeoutException e2)
{
Debug.WriteLine("If you don't see this in the output window then somehow you are not running this app.");
writeToLog(e2.ToString());
}
//...
I am working on C# console application.
Want to impliment "Exception Handling".
Below are the code of ConsoleApp.
static public void Main(string[] args)
{
try
{
for (int i = 0; i < 10; i++)
{
ONE_IndependentProcess(i);
}
TWO_IndependentProcess();
THR_IndependentProcess();
}
catch (System.TimeoutException ex)
{
Console.WriteLine("System.TimeoutException");
}
catch (System.Exception ex)
{
Console.WriteLine("System.Exception");
}
finally
{
Console.WriteLine("End.");
}
}
If an error occurs in TWO_IndependentProcess... application stops, without executing the THR_IndependentProcess
#1. In this case i want THR_IndependentProcess to be execute, and write a Exception Error Information of TWO_IndependentProcess in the Console.
If an error occurs in the ONE_IndependentProcess(3) (in 3rd iteration) application stops, without executing the: remaining iteration(4 to 9), TWO_IndependentProcess & THR_IndependentProcess
#2. In this case also i want the app to execute all, and just write a Exception Error Information of ONE_IndependentProcess(3) in the Console.
Note: I have four Catch block with Detail Exception Information and i want to apply all these four catch block in all three IndependentProcess function.
I would recommend you keep just one copy of your error handling logic and make use of lambda functions to wrap the calls with it:
static private void WithCatch(Action f)
{
try
{
f();
}
catch (System.TimeoutException ex)
{
Console.WriteLine("System.TimeoutException");
}
catch (System.Exception ex)
{
Console.WriteLine("System.Exception");
}
}
static public void Main(string[] args)
{
WithCatch(() => {
for (int i = 0; i < 10; i++)
ONE_IndependentProcess(i);
});
// You could also do this inside the for loop for each one if you want
// to attempt all 10 even if one fails:
//for (int i = 0; i < 10; i++)
// WithCatch(() => {ONE_IndependentProcess(i);});
WithCatch(() => {TWO_IndependentProcess();});
WithCatch(() => {THR_IndependentProcess();});
}
You need to move each independent process into a separate try/catch block.
e.g.
static public void Main(string[] args)
{
try
{
for (int i = 0; i < 10; i++)
{
ONE_IndependentProcess(i);
}
}
catch (System.TimeoutException ex)
{
Console.WriteLine("System.TimeoutException");
}
catch (System.Exception ex)
{
Console.WriteLine("System.Exception");
}
finally
{
Console.WriteLine("End.");
}
try
{
TWO_IndependentProcess();
}
catch (System.TimeoutException ex)
{
Console.WriteLine("System.TimeoutException");
}
catch (System.Exception ex)
{
Console.WriteLine("System.Exception");
}
finally
{
Console.WriteLine("End.");
}
try
{
THR_IndependentProcess();
}
catch (System.TimeoutException ex)
{
Console.WriteLine("System.TimeoutException");
}
catch (System.Exception ex)
{
Console.WriteLine("System.Exception");
}
finally
{
Console.WriteLine("End.");
}
}
You will have to use catch blocks within independent functions/process and deal with the exception within that catch block. This way you can allow program execution to continue without terminating.
try using generic functions to record exceptions - that way you can reuse this function within different catch blocks.
Below is some of my error logging code. When an exception happens inside my app, I log it to a database. If that database is down or when there's some other problem, I try to log it in an event viewer.
What happens if that event viewer write fails for some reason, too? How do I give up or swallow this new exception?
void SaveLog(string accountId, Exception ex, Category category, Priority priority)
{
try
{
using (var connection = new SqlConnection(…))
{
connection.Open();
command.ExecuteNonQuery();
}
}
catch (Exception exception)
{
// exception while logging!
using (var eventLog = new EventLog { Source = "tis" })
{
eventLog.WriteEntry(
exception.Message + Environment.NewLine +
exception.StackTrace,
EventLogEntryType.Error);
}
}
}
try {
// ...
}
catch (Exception exception) {
try {
// Attempt to write to event log.
}
catch {
}
}