Reputation: 7980
I am writing a logger for a legacy codebase written in VB.NET which contains a lot of events and functions which have the form:
Try
'Do some stuff here'
Catch ex As Exception
'Handle the exception here'
EndTry
Where the Try
statement is the first line of the method and the EndTry
is the last line of the method. Because the code hasn't been maintained over the years, no one is sure if the try-catches are actually necessary. Now, I have written a singleton class that hooks into a logging framework and I can call it like so:
With New MyLogger().Logger
Try
'Do some stuff here'
Catch ex As Exception
.Log("Some message", ex)
EndTry
EndWith
where MyLogger
is written in .NET 4.0. What I'd like to do here, is remove the inner try-catch and replace it with some event handler in MyLogger
. I already have AppDomain.CurrentDomain.UnhandledException
wired up but my understanding is that the event will only raise with exceptions that pass all the way through the application without being caught. Is there an event I can handle that will only catch exceptions that make it to the given scope where the object is newed up at? Maybe it would look something like this:
public MyLogger()
{
Something.CurrentScope.UnhandledException += MyHandler;
}
private MyHandler(object sender, UnhandledExceptionEventArgs args)
{
// log the exception here
}
with the following VB.NET code:
With New MyLogger().Logger
'Do some stuff here'
EndWith
Any help would be appreciated, thanks!
Upvotes: 1
Views: 131
Reputation: 38931
It seems you are looking for a scope-local handler, and I'm pretty positive that there is no such thing as such.
However, you presented:
With New MyLogger().Logger Try 'Do some stuff here' Catch ex As Exception .Log("Some message", ex) EndTry EndWith
which should, with appropriate initialization, simplify to something along the lines of:
With New MyLogger().Logger 'Do some stuff here' EndWith
I think that a lambda wrapper could help you here:
Essentially, instead of doing With Logger ... EndWith
you're gonna do:
MyLogger().DoWithCatch(
Sub()
' Do some stuff here
End Sub
)
where DoWithCatch
would be implemented like
Sub DoWithCatch(ByVal lambda As Sub())
Try
lambda()
Catch ex As Exception
Log("Some message", ex)
EndTry
End Sub
I think you get the idea.
This way, you only write the catch block once.
Possibly, what you are looking for is: AppDomain.FirstChanceException Event
; docs
Provides data for the notification event that is raised when a managed exception first occurs, before the common language runtime begins searching for event handlers.
Another global way to be "notified" of all exceptions is to use Vectored Exception Handling. But that seems to be unmanaged only.
Ref: Is it possible to do Vectored Strctured exception handling in c#?
Upvotes: 1