I posted this question in microsoft.public.dotnet.framework.interop but got
zero replies in 5 days so I'm reposting in the general framework group hoping
someone's got some insight:

We have a large IIS/SQL classic ASP site that we are converting to .NET by
abstracting functionality into .NET components/methods which are also
installed/registered as COM objects so they can by invoked by new ASPX pages
as well as by our current ASP pages (Set xxx = Server.CreateObject)

My question is how do I hook a handler into the UnhandledException chain for
my ASP page invoked components via (Set ThisObj =
Server.CreateObject("MyLib:MyObj")?

The section of my code where I hook the chain is:

If System.Web.HttpContext.Current Is Nothing Then
'Instantiated in the classic ASP environment
' ??? What goes here ???
Else
'Instantiated in the ASPX environment
Dim HttpApplication As System.Web.HttpApplication =
System.Web.HttpContext.Current.ApplicationInstance
AddHandler HttpApplication.Error, AddressOf HandleHttpExceptions
' This works fine to catch exceptions in the .NET assembly on
ASPX pages
End If

I've tried the standard console application hooking:

Dim CurrentDomain As AppDomain = System.AppDomain.CurrentDomain
AddHandler CurrentDomain.UnhandledException, AddressOf
HandleUnhandledExceptions

but that doesn't seem to work across the interop/COM boundaries.

Anybody got any light to shed on where the UnhandledException event chain
lives when the .NET assembly is registered as a COM object and invoked by
IIS's object structure?

Re: Hooking UnhandledException in .NET module invoked in classic ASP by David

David
Mon Mar 07 10:58:55 CST 2005


"John Snook" <JohnSnook@discussions.microsoft.com> wrote in message
news:44117C22-276F-4722-BFC4-71F739A06049@microsoft.com...
>I posted this question in microsoft.public.dotnet.framework.interop but got
> zero replies in 5 days so I'm reposting in the general framework group
> hoping
> someone's got some insight:
>
> We have a large IIS/SQL classic ASP site that we are converting to .NET by
> abstracting functionality into .NET components/methods which are also
> installed/registered as COM objects so they can by invoked by new ASPX
> pages
> as well as by our current ASP pages (Set xxx = Server.CreateObject)
>
> My question is how do I hook a handler into the UnhandledException chain
> for
> my ASP page invoked components via (Set ThisObj =
> Server.CreateObject("MyLib:MyObj")?
>
> The section of my code where I hook the chain is:
>
> If System.Web.HttpContext.Current Is Nothing Then
> 'Instantiated in the classic ASP environment
> ' ??? What goes here ???
> Else
> 'Instantiated in the ASPX environment
> Dim HttpApplication As System.Web.HttpApplication =
> System.Web.HttpContext.Current.ApplicationInstance
> AddHandler HttpApplication.Error, AddressOf
> HandleHttpExceptions
> ' This works fine to catch exceptions in the .NET assembly on
> ASPX pages
> End If
>
> I've tried the standard console application hooking:
>
> Dim CurrentDomain As AppDomain = System.AppDomain.CurrentDomain
> AddHandler CurrentDomain.UnhandledException, AddressOf
> HandleUnhandledExceptions
>
> but that doesn't seem to work across the interop/COM boundaries.
>
> Anybody got any light to shed on where the UnhandledException event chain
> lives when the .NET assembly is registered as a COM object and invoked by
> IIS's object structure?


I beleive that the managed exception is "handled" by the CCW. The exception
is caught and and a COM error is passed to COM. So the error propagates out
to the COM client and it is not unhandled. It's up to the COM client to do
something useful with the error then.

David



Re: Hooking UnhandledException in .NET module invoked in classic A by JohnSnook

JohnSnook
Mon Mar 07 16:29:08 CST 2005

Hi David,

Many thanks for the response (I was getting a little lonely with no
replies!) and yes, you're right - that's exactly what happens because the CCW
is hooked into the propagation chain of the exception. What I want to do is
hook into that chain in my assembly ("nearer" to the exception) save some
information about the exception and then let it propagate on to the CCW and
thereafter COM and thereafter IIS (where we use a user friendly HTTP 500 ASP
page)

I can't do that with
System.Web.HttpContext.Current.ApplicationInstance.UnhandledException event
(as you would with an ASPX page) and
System.AppDomain.CurrentDomain.UnhandledException event (as you would with a
console app executable)

What "ApplicationDomain" is my assembly running under in the
IIS->ASP->COM->CCW->MyAssembly world (or at least how do I reference it) ??
But your use of the CCW keyword has triggered a new line of Googling ...

Rgds, JS

"David Browne" wrote:

>
> I beleive that the managed exception is "handled" by the CCW. The exception
> is caught and and a COM error is passed to COM. So the error propagates out
> to the COM client and it is not unhandled. It's up to the COM client to do
> something useful with the error then.
>
> David
>

Re: Hooking UnhandledException in .NET module invoked in classic A by David

David
Mon Mar 07 19:10:12 CST 2005


"John Snook" <JohnSnook@discussions.microsoft.com> wrote in message
news:8FB332CA-66C1-4BA6-A81A-21D6A7175004@microsoft.com...
> Hi David,
>
> Many thanks for the response (I was getting a little lonely with no
> replies!) and yes, you're right - that's exactly what happens because the
> CCW
> is hooked into the propagation chain of the exception. What I want to do
> is
> hook into that chain in my assembly ("nearer" to the exception) save some
> information about the exception and then let it propagate on to the CCW
> and
> thereafter COM and thereafter IIS (where we use a user friendly HTTP 500
> ASP
> page)
>
> I can't do that with
> System.Web.HttpContext.Current.ApplicationInstance.UnhandledException
> event
> (as you would with an ASPX page) and
> System.AppDomain.CurrentDomain.UnhandledException event (as you would with
> a
> console app executable)
>
> What "ApplicationDomain" is my assembly running under in the
> IIS->ASP->COM->CCW->MyAssembly world (or at least how do I reference it)
> ??
> But your use of the CCW keyword has triggered a new line of Googling ...
>

In the past I have structured every method in my COM visible class like:

void foo()
{
try
{
//method body
}
catch (Exception ex)
{
//log error and do whatever
throw;
}
}

David




Re: Hooking UnhandledException in .NET module invoked in classic A by JohnSnook

JohnSnook
Tue Mar 08 12:57:04 CST 2005

Hi David,

Yes, thats an approach. But in this conversion project we'll be implementing
perhaps two hundred methods (although only, say half, of those will require
instantiation in IIS as COM objects) so a try/catch/finally on every method
and property gets pretty tedious (to create AND read).

We've got plenty of try/catch blocks where we "expect" (???) errors such as
foreign key constraints or bad data submitted but for the "acts of God"
errors (somebody killed the SQL cluster or chopped through a network link) we
just want to log some key info before the error disappears as a HTTP500 error
on an ASP page. Isn't that what structured error handling and
UnhandledException events were invented for?

Later ... JS

"David Browne" wrote:

>
> In the past I have structured every method in my COM visible class like:
>
> void foo()
> {
> try
> {
> //method body
> }
> catch (Exception ex)
> {
> //log error and do whatever
> throw;
> }
> }
>
> David
>
>
>
>

Re: Hooking UnhandledException in .NET module invoked in classic A by David

David
Tue Mar 08 13:15:48 CST 2005


"John Snook" <JohnSnook@discussions.microsoft.com> wrote in message
news:42B8DB50-DE1E-4EA9-BDBC-4C7D531309D7@microsoft.com...
> Hi David,
>
> Yes, thats an approach. But in this conversion project we'll be
> implementing
> perhaps two hundred methods (although only, say half, of those will
> require
> instantiation in IIS as COM objects) so a try/catch/finally on every
> method
> and property gets pretty tedious (to create AND read).

Your COM-visible classes are lame anyway. They can't have meaningful
constructors or have static methods, etc. Treat them as adapter classes in
your design and expect them to be full of tedius marshaling stuff. Put your
implementation in better-designed, non-COM visible objects.

>
> We've got plenty of try/catch blocks where we "expect" (???) errors such
> as
> foreign key constraints or bad data submitted but for the "acts of God"
> errors (somebody killed the SQL cluster or chopped through a network link)
> we
> just want to log some key info before the error disappears as a HTTP500
> error
> on an ASP page. Isn't that what structured error handling and
> UnhandledException events were invented for?
>

Yes. But you are handing the error information to classic asp, which
doesn't support structured error handling.

So you should probably capture the error info before you let enter the black
hole of script that is old ASP.

On a more general level, you shold probably trap and log all errors as they
pass through major system boundries.

David



Re: Hooking UnhandledException in .NET module invoked in classic A by JohnSnook

JohnSnook
Tue Mar 08 17:35:09 CST 2005



"David Browne" wrote:

>
> Your COM-visible classes are lame anyway. They can't have meaningful
> constructors or have static methods, etc. Treat them as adapter classes in
> your design and expect them to be full of tedius marshaling stuff. Put your
> implementation in better-designed, non-COM visible objects.
>
> Yes. But you are handing the error information to classic asp, which
> doesn't support structured error handling.
>
> So you should probably capture the error info before you let enter the black
> hole of script that is old ASP.
>
> On a more general level, you shold probably trap and log all errors as they
> pass through major system boundries.
>
> David
>
Hi David

I don't disagree and would love to scrap everything and start with a clean
(non-COM visible) sheet of paper but with tens of thousands of lines of
linear, interpretative, procedural ASP code in a two tier system getting
several million hits a day our chosen path is progressive abstraction into a
three tier design until the ASP/COM side just "goes away". Alas I can't scrap
it and start again. And yes, there's an awful lot of marshalling but I let
.NET worry about that.

I don't mind the error propagating into the unstructured black hole of ASP
(where it's covered up by a user friendly page anyway) so long as I get to
"capture the error info before" and log it. Do you (or anybody) know how to
do that (short of a try/catch around each method) when the assembly is
running inside of a CCW inside of a dllhost.exe inside of inetinfo.exe ? If
nobody does know how to hook into that unhandled exception chain then I
probably will have to code try/catch around the methods.

Bear in mind we're not trying to handle the "standard" errors (we already do
that) but grab meaningful forensic info on the rarer errors. For example a
recent rebuild of one of the 10 web servers left the "recycle worker threads"
option in place on IIS so that about every 2 weeks one page hit failed. But
it failed semi-silently making it difficult to know that it had happened let
alone find out why.

Later ... JS



RE: Hooking UnhandledException in .NET module invoked in classic ASP by JohnSnook

JohnSnook
Thu Mar 10 07:31:07 CST 2005

Anybody who's also looking to hook .NET exceptions where the assembly is
invoked in classic ASP (via COM Callable Wrapper) should take a look at an
excellent MSDN (January 2005) article by Matt Adamson that lays out the
issues and offers a full (downloadable) solution:

http://msdn.microsoft.com/msdnmag/issues/05/01/ExceptionLogging/default.aspx