Camillia
asked on
Error trapped but why didn't the code move to the next method ?
I'm working with a VB.net code base that was written 10 yrs ago or so.
I don't understand why the code didn't continue after the error that was thrown. I will go step by step
1. Code calls several methods
2. Code is scheduled as a service and runs every 10 mins. Code went thru the methods and got to and threw an error
3. Error is that it lost connection to the database
Exception : System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) ---> System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified
4. Code is like this for that method
5. So this is what happened
a. Emailed the error in "Catch" section of outer/main Try-catch. This is good.
b. It did NOT log this even tho it's in "catch" section outer/main Try-Catch
c. It did NOT move to the next method to process. It trapped the error, sent the email, why didn't it go to the next one?
I don't understand why the code didn't continue after the error that was thrown. I will go step by step
1. Code calls several methods
Process_Outbound_Shipment_945_V2()
Process_Outbound_ShipmentConfirmation()
Process_Outbound_PickPackConfirmation()
Process_Outbound_InventoryAdjustments() //**** error happened here
Process_Outbound_Inventory()
Process_Outbound_Inventory_V2()
Process_Outbound_Inventory_V3()
2. Code is scheduled as a service and runs every 10 mins. Code went thru the methods and got to and threw an error
Process_Outbound_InventoryAdjustments()
3. Error is that it lost connection to the database
Exception : System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) ---> System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified
4. Code is like this for that method
Private Sub Process_Outbound_InventoryAdjustments()
Try '**** outer try that wraps the entire
LogEntry("processing ....")
trUpdate = cnPronto1.BeginTransaction
Dim cmdUpdate As SqlCommand
cmdUpdate = cnPronto1.CreateCommand
cmdUpdate.CommandTimeout = 600
cmdUpdate.Transaction = trUpdate
Try
'code here
cmdUpdate.CommandText = "insert into whatever table "
......
cmdUpdate.CommandTimeout = 600
intRecords = cmdUpdate.ExecuteNonQuery()
trUpdate.Commit()
Catch ex2 As SqlException
If Not trUpdate.Connection Is Nothing Then
' do stuff here
End If
Try
trUpdate.Rollback()
Catch ex1 As Exception
'''''
End Try
Finally
trUpdate.Dispose()
End Try
cnPronto2 = New SqlConnection
cnPronto2.ConnectionString = strWMSConnect
cnPronto2.Open() '*** error happened here******
'**** outer catch for try
Catch ex As Exception
Send_Error() '*** emailed the error
LogEntry("The following exception of type " & ex.GetType().ToString() &
" was encountered while attempting to do the Main Section:")
'closes connections here
Finally '***** outer Finally for outer try
'closes connectons
End Try ''*** outer try
LogEntry("Done")
End Sub
5. So this is what happened
a. Emailed the error in "Catch" section of outer/main Try-catch. This is good.
Send_Error() '*** emailed the error
b. It did NOT log this even tho it's in "catch" section outer/main Try-Catch
LogEntry("The following exception of type " & ex.GetType().ToString() &
" was encountered while attempting to do the Main Section:")
c. It did NOT move to the next method to process. It trapped the error, sent the email, why didn't it go to the next one?
Process_Outbound_InventoryAdjustments()
Process_Outbound_Inventory() '** why didn't it come here?
Process_Outbound_Inventory_V2()
Process_Outbound_Inventory_V3()
Process_Outbound_OrderStatus()
Process_Outbound_EventMessages()
Process_Outbound_WorkOrderConfirmation()
6. Send_Error does thisPrivate Sub Send_Error()
Dim msg As New MailMessage
msg.From = New MailAddress(".....")
msg.To.Add(strNotificationEmailRecipients)
msg.Priority = MailPriority.Normal
msg.Subject = "Error Notification"
msg.Body = "An error was recorded in log file on " & Format(Now(), "F") & "."
Dim smtp As New SmtpClient(strSMTPIPAddress)
Try
smtp.Send(msg)
Catch ex As Exception
Dim ex2 As Exception = ex
Dim errorMessage As String = String.Empty
While Not (ex2 Is Nothing)
errorMessage += ex2.ToString()
ex2 = ex2.InnerException
End While
LogEntry("The following exception was encountered while attempting to send email:")
LogEntry("Message : " + errorMessage)
End Try
End Sub
If I understand correctly it should run the next function. How do you know it isn't doing that.
can you try adding Network Library=DBMSSOCN to your connection string? It looks like you are by default trying to connect through name pipe which is not very common.
ASKER
1. >>If I understand correctly it should run the next function. How do you know it isn't doing that.
Because it didn't log the next process in the log file. It just stopped at that network error. Each method that is called logs something like "this method is being processed"
I also think it should've gone to the next method. I don't know why it didn't.
2. This is the database string connection. It somehow lost network connection. Add it here?
3. Another question. This is a critical application. I want to make sure all methods are processed. I was talking with my manager and he suggested wrapping each method in "try/catch" so if one method fails, the other ones will get processed.
Should I do it like this?
try
Process_Outbound_InventoryAdjustments()
catch
'send email
End
try
Process_Outbound_Inventory()
catch
'send email
end
Or like this? a nested one
try
Process_Outbound_InventoryAdjustments()
catch
'send email
Finally
try
Process_Outbound_Inventory()
catch
'send email
Finally
try
whateverprocess()
catch
'send email
Finally
End
End
Because it didn't log the next process in the log file. It just stopped at that network error. Each method that is called logs something like "this method is being processed"
I also think it should've gone to the next method. I don't know why it didn't.
2. This is the database string connection. It somehow lost network connection. Add it here?
strWMSConnect = "data source=" & strWMSIPAddress & ";initial catalog=" & strWMSDatabase & ";user id=" & strWMSDbUsername & ";password=" & strWMSDbPassword
3. Another question. This is a critical application. I want to make sure all methods are processed. I was talking with my manager and he suggested wrapping each method in "try/catch" so if one method fails, the other ones will get processed.
Should I do it like this?
try
Process_Outbound_InventoryAdjustments()
catch
'send email
End
try
Process_Outbound_Inventory()
catch
'send email
end
Or like this? a nested one
try
Process_Outbound_InventoryAdjustments()
catch
'send email
Finally
try
Process_Outbound_Inventory()
catch
'send email
Finally
try
whateverprocess()
catch
'send email
Finally
End
End
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
>>Could your logging routine be buggy in that the function is being called but the entry in the log not being written?
This is such a messy code that anything is possible.
>>I'd put a breakpoint where the exception is being caaught then try single stepping to see just what code is actually being executed afterwards.
This is a good idea. I'll throw an error in that same method, same line and see what it does. I can't recreate the network error but I'll create another custom error for testing
This is such a messy code that anything is possible.
>>I'd put a breakpoint where the exception is being caaught then try single stepping to see just what code is actually being executed afterwards.
This is a good idea. I'll throw an error in that same method, same line and see what it does. I can't recreate the network error but I'll create another custom error for testing
what is the code behind LogEntry? If it is logging into a SQL database and you have lost the connection, chances are that you will not be able to log the error!
I would't nest the try catch like you show in your second sample. It is useless in this specific case.
I would't nest the try catch like you show in your second sample. It is useless in this specific case.
ASKER
>>what is the code behind LogEntry? If it is logging into a SQL database and you have lost the connection, chances are that you will not be able to log the error!
It's a text file.
>>I would't nest the try catch like you show in your second sample. It is useless in this specific case.
I want to make sure if one method fails, others get processed...regardless of this network error. Still not do nesting? what else can I do?
Let me step thru the code and generate a custom error as Andrew suggested and see why it didn't process the next one.
It's a text file.
>>I would't nest the try catch like you show in your second sample. It is useless in this specific case.
I want to make sure if one method fails, others get processed...regardless of this network error. Still not do nesting? what else can I do?
Let me step thru the code and generate a custom error as Andrew suggested and see why it didn't process the next one.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
>>if each method handles correctly errors and are not rethrowing the error, there is no need to nest your calls.
That's the thing. This is a convoluted code from 10 yrs ago. 40,000 something rows of code in one file. I'm looking to patch it because we're going to rewrite it. I don't want to spend time fixing this old code.
I'll test the nested error handling as well.
That's the thing. This is a convoluted code from 10 yrs ago. 40,000 something rows of code in one file. I'm looking to patch it because we're going to rewrite it. I don't want to spend time fixing this old code.
I'll test the nested error handling as well.
ASKER
I debugged it by throwing a custom (division by zero) around the same line (thanks, Andy. )Found out why it didn't go to the next process. It catches the error, emails (so far so good) but then it tries to close connects in Finally which haven't been set....they're null. For example, in Finally, it wan't to close this and it's null so it can't catch it and it can't handle it. So, the entire process breaks.
Eric, I think you're right that if the error handling was done correctly, I wouldn't need a nested Try/Catch. I won't do that.
If (cnPronto3.State = ConnectionState.Open) Then
cnPronto3.Close()
End If
Eric, I think you're right that if the error handling was done correctly, I wouldn't need a nested Try/Catch. I won't do that.
If (cnPronto3.State = ConnectionState.Open) Then
cnPronto3.Close()
End If
a really nice feature to handle/close/dispose objects in .Net that wouldn't trigger that kind of issue would be to use the Using statement as shown in https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/using-statement
ASKER
Yea, Using statement. I'll fix this for now and then I'll see what it takes to change all this.
Messy code doesn't even describe this code base.
Thanks for the help.
Messy code doesn't even describe this code base.
Thanks for the help.
I still dont get why it didnt log, yeah it sends email, but before trying to close connections shouldnt it first log?
ASKER
It didn't log because it got to the try/catch. In try/catch, it sent the email. Now, it wanted to close a connection. The variable is xyz. But this xyz is null so the catch section also had an error. Goes to Finally and it tries to use the same parameter that is null. Code can't handle it. It just sits there and doesn't do anything else.
I added a check for null for the parameters.
I added a check for null for the parameters.