views:

151

answers:

2

My goal here is to get stack trace information from a dynamically loaded assembly. If the dynamically loaded assembly just throws the error back to the caller, the stack trace information doesn’t tell you the location in the dynamic assembly where the error occurred. If I throw my own exception, passing in the original exception, it will get added as an inner exception and will have the information need. I’m trying to avoid changing all my dynamic assemblies to throw new exceptions. Does anybody know a better way to get the stack trace information from a dynamically loaded assembly?

Public Class ErrorPlugin
    ' Example Function from plug in DLL
    Public Function SimpleExample() As Double


        Dim RentedUnits As Double = 42
        Dim NumberUnits As Double = 0


        Try

            ' Just need to generate exception
            Return RentedUnits \ NumberUnits

        Catch ex As Exception

            ' Give's me no Stack Trace infomation.
            'Throw

            ' This will give me Stack Trace infomation, 
            ' but requires adjusting all the plugins.
            Throw New Exception("Stop dividing by zero.", ex)

        End Try



    End Function
End Class



Imports System.Reflection
Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


        Dim rpt As Object
        Dim r As Double

        Try

            rpt = LoadReport("C:\ErrorPlugin\bin\Debug\ErrorPlugin.dll")

            r = rpt.SimpleExample()

        Catch ex As Exception

            MsgBox(ex.Message & vbCrLf & ex.StackTrace)

            If ex.InnerException IsNot Nothing Then
                MsgBox(ex.InnerException.StackTrace)
            End If

        End Try


    End Sub


    Public Function LoadReport(ByVal FileName As String) As Object

        Dim m_ReportAssembly As [Assembly]
        Dim m_ReportClass As Type
        Dim rpt As Object

        Try
            m_ReportAssembly = Assembly.LoadFrom(FileName)
            For Each m_ReportClass In m_ReportAssembly.GetTypes
                If m_ReportClass.Name.ToLower = "ErrorPlugin".ToLower Then
                    rpt = Activator.CreateInstance(m_ReportClass)
                    Exit For
                End If
            Next

            Return rpt

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Function

End Class
+2  A: 

Can you see what happens if you just Throw, not Throw ex? From memory, "throw ex" does a copy while "throw" actually rethrows the caught exception. I guess your "throw ex" is effectively resetting the stack trace to your local code.

MSDN says if you're rethrowing exceptions you should add value to it by wrapping it in a new exception, otherwise you might as well not bother with try/catch in your example.

Daniel Ives
A: 

Do you have the debug symbols for these external DLL's? If you look at the stack trace, and it reads "External Code", that should be expanded into the DLL stack if you have the DLL debug symbols loaded while debugging, since the symbols will provide your debugger with the necessary info to walk the stack.

Either do this by manually loading the symbols, via the Modules Window in the Debug menu, or running against a debug build of the DLL.

Wez