Link to home
Start Free TrialLog in
Avatar of Camillia
CamilliaFlag for United States of America

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
        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()

Open in new window


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()

Open in new window


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

Open in new window


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

Open in new window


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:")

Open in new window


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()

Open in new window

6. Send_Error does this

Private 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

Open in new window

Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

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.
Avatar of Camillia

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?
 strWMSConnect = "data source=" & strWMSIPAddress & ";initial catalog=" & strWMSDatabase & ";user id=" & strWMSDbUsername & ";password=" & strWMSDbPassword

Open in new window


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
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>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

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.
>>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.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>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.
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
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
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. 
Avatar of Arana (G.P.)
Arana (G.P.)

I still dont get why it didnt log, yeah it sends email, but before trying to close connections shouldnt it first log?
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.