0

Hi there I am carrying out some integration testing in an application I am developing. The specific element that is causing an issue is a call to a background worker which interrogates an Oracle database. When an error is encountered in the query I want the exception detail to percolate up the call stack to the application level and at that point provide an appropriate user compatible message. In the example test there is a syntax error in the underlying SQL which results in an OraEx Exception:

Oracle.DataAccess.Client.OracleException ORA-00907: missing right parenthesis

Unfortunately the code generates the following exception:

System.Reflection.TargetInvocationException was unhandled
Message: An unhandled exception of type
'System.Reflection.TargetInvocationException' occurred in mscorlib.dll
Additional information: Exception has been thrown by the target of an
invocation.

in the DoWork sub of the backgroundworker, despite my belief that I am handling the exception correctly. Its pretty obvious that I am missing something fundamental here, can someone suggest a solution please.

Thanks in Advance Paul J.

Here is the code that makes the call to the background worker:

Private Sub EventSearch(ByVal mySQL As String)

    Const procName As String = "EventSearch"

    Try
        _eventMngr = New ScadaEventManager(_CurrentDB, _userName, _myPwd)
        _eventMngr.SQL = mySQL

        'Set the flag and stop query tool status accordingly
        _Stopped = False
        uxStopQueryTool.Enabled = True

        'activate the timer object to ensure that the execute query menu 
        'and tool remain disabled until all background processing is complete
        uxBackWorkTimer.Enabled = True

        _logger.SendLog(Me.Name & "." & procName & " - Scanning for data.", NLog.LogLevel.Trace)
        ReviseStatus(2, "Scanning for data.  Please wait...", Color.Black, True, True)

        'Force the thread to sleep for half a second so the user can see the scanning state taking place
        Threading.Thread.Sleep(500)

        'Launch the background worker to retrieve the required data from the database
        uxBWScan.RunWorkerAsync(_eventMngr)

    Catch ex As Exception

        MsgBox(ex.Message, MsgBoxStyle.Exclamation, My.Application.Info.ProductName)
        _logger.SendLog(ex.Message & ".  Thrown in module " & Me.Name.ToString & "." & procName, NLog.LogLevel.Error, ex)
        Call ResetStatus()

    Finally

    End Try

End Sub

And here is the code executed by the background worker:

Private Sub uxBWScan_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles uxBWScan.DoWork
    Const procName As String = "uxBWScan_DoWork"
    Try
        e.Argument.CountRecords(_queryTypeID)
        e.Result = e.Argument.RecordCount
    Catch NullEx As NullReferenceException
        _logger.SendLog(NullEx.Message & ".  Thrown in module " & Me.Name.ToString & "." & procName, NLog.LogLevel.Error, NullEx)
        Throw
    Catch OraEx As OracleException
        _logger.SendLog(OraEx.Message & ".  Thrown in module " & Me.Name.ToString & "." & procName, NLog.LogLevel.Error, OraEx)
        Throw
    Finally
    End Try
End Sub

And here is the low level code that generates the error:

    Public Sub CountRecords(ByVal queryType As Integer)

        _myDataset = New DataSet
        Try
            _myDataset = _myScadaEventDB.CountRecords(_sqlText)
            If _myDataset.Tables(0).Rows.Count > 0 Then
                If queryType = Enums.QueryType.General Or queryType = Enums.QueryType.KeyPerformanceIndicators Or queryType = Enums.QueryType.TelecontroAnalysis Then
                    _recordCount = _myDataset.Tables(0).Rows(0).Item("RecordCount")
                Else
                    'The query is grouped therefore count the number of records in the table 
                    _recordCount = _myDataset.Tables(0).Rows.Count
                End If
            Else
                _recordCount = 0
            End If
        Catch ex As Exception
            Throw
        Finally

        End Try

    End Sub
Paul Johnson
  • 213
  • 3
  • 14
  • Check the inner exception to get more details (and quite possibly the exception that you're expecting to see). – NoAlias Mar 15 '17 at 17:15
  • 1
    When you call `CountRecords` on the event argument, is that early-bound or late-bound? What's the type of `e.Argument`? I suspect this might be a late-bound call, thus the exception being wrapped in a `TargetInvocationException`. As per the comment above, you can look at the `InnerException` of the `TargetInvocationException` to see if it's what you expected. – Craig Mar 15 '17 at 17:50
  • @Craig : It's a late-bound call. The [**`DoWorkEventArgs.Argument` property**](https://msdn.microsoft.com/en-us/library/system.componentmodel.doworkeventargs.argument(v=vs.110).aspx) is an `Object`. – Visual Vincent Mar 15 '17 at 19:29
  • Guys, thanks for your feedback. I can confirm it is a late-bound call. The error being generated is as expected, however as I already stated the problem is that the exception is not percolating up the call stack as I expected. The targetinvocationexception is being generated within the DoWork procedure of the worker. I should perhaps have pointed out that the application allows the user to customise/edit the SQL statement, hence the reason for the test. – Paul Johnson Mar 16 '17 at 10:29

1 Answers1

0

Ok, problem solved. Removed the try catch block from DoWork and moved my exception handling into 'RunWorkerCompleted' using e.error. Some reading of the documentation (RTFM...), highlighted the fact that using Try/Catch in the worker thread interferes with the native functionality of the BackgroundWorker. Thanks again everyone for your input.

Paul,

Paul Johnson
  • 213
  • 3
  • 14