7

The code is fairly simple --- the issue is that there is an invalid character in the groupPath string (a '/' to be exact).

What I'm trying to do (at least as a stop gap) is skip over DirectoryEntries that I can't get the cn for --- regardless of why.

However when I run this code the catch block doesn't run and I get instead: The server is not operational. and an unhandled System.Runtime.InteropServices.COMException.

Why would the catch block not catch this exception.

try
{
    using (DirectoryEntry groupBinding = new DirectoryEntry("LDAP://" + groupPath))
    {
        using (DirectorySearcher groupSearch = new DirectorySearcher(groupBinding))
        {

            using (DirectoryEntry groupEntry = groupSearch.FindOne().GetDirectoryEntry())
            {
                results.Add(string.Format("{0}", groupEntry.Properties["cn"].Value.ToString()));
            }
        }
    }
}
catch
{
    Logger.Error("User has bad roles");
}

Additional observations: The code is actually in a custom RoleProvider, and the curious thing is that if I reference, this provider in a simple winforms app, and call this same method with the same inputs the catch block does exactly what it's suppose to do. I think this suggests that the proposed answer concerning .NET exceptions versus COM exceptions is not accurate. Although I am at a loss to understand why this code would not catch when executed from the WebDev server

Ralph Shillington
  • 20,718
  • 23
  • 91
  • 154
  • 4
    in the debugger, or in the build? – Tom Anderson May 22 '09 at 16:24
  • What line do you get the exception on? And what thread? – lc. May 22 '09 at 16:30
  • 2
    Also, can you add the exception? (Exception.ToString()) – Tom Anderson May 22 '09 at 16:33
  • I wonder if maybe the exception is being thrown in one of the implicit Finally blocks wrapping the Disposes produced by the Using statements? Aren't there some odd exception handling rules within Finally blocks? Anyhow, on the off chance that's the case, I'd pull the Using statements and code it out long hand to get a better handle on where exactly the exception occurs. – ewbi May 22 '09 at 16:55
  • You are not debugging in release mode, are you ? Otherwise weird things like this could happen. – Mez May 23 '09 at 02:05

5 Answers5

13

When you don't specify what to catch, it defaults to .NET exceptions. Your exception is in COM where .NET isn't set to catch the exception. The best way to deal with this is to catch the COM exception, which should look something like this:

    try
    {

    }
    catch (System.Runtime.InteropServices.COMException COMex)
    {

    }
    catch (System.Exception ex)
    {

    }
Noah
  • 13,821
  • 4
  • 36
  • 45
  • COMException inherits ExternalException inherits SystemException inherits Exception. Unless there is something I am missing, this should not be the case of missing the catch, perhaps just adding he System.Exception catch? – Tom Anderson May 22 '09 at 16:58
  • COMException may inherit from System.Exception, but it's still not caught in the COM interop with System.Exception. I've done a lot of interop with AutoCAD and this drove me crazy for quite awhile since I was so used to using the catch all instead of specifying my exact exceptions. – Noah May 22 '09 at 17:00
  • woah hold the phone - are you serious!? Clearly you are but that's really surprising and really bad! Does this happen for any other ExternalException types? – Rory May 22 '09 at 18:20
  • I've only really played around with it in AutoCAD and I had to use Autodesk.AutoCAD.Runtime.Exception quite a bit, and this derives from System.Exception. I spent a few days trying to figure out why my catches were crashing AutoCAD, when I thought I was handling the exception properly. – Noah May 22 '09 at 18:25
  • Noah, if he'd used catch (Exception ex) {...} would it have caught the COMException, in your experience? ie Does the weirdness happen only when you don't specify any exception type, or does it always happen unless you specify COMException exactly? – Rory May 22 '09 at 18:27
  • Can you point to any further discussion or examples of this - I'm quite interested. thanks. – Rory May 22 '09 at 18:27
  • I could be totally wrong here, but in my experience, I've had to specify the COMException to catch it as the exception occurs in unmanaged code outside of the CLR. I'll try some googling to see what MS says. I'm sure they've devoted some articles on MSDN for this. – Noah May 22 '09 at 18:32
  • Well, it seems that MS quite vague about this but it's best practices (http://msdn.microsoft.com/en-us/library/seyhszts.aspx) say you should try to catch the exact exception that will be thrown... personally I only use the Interop exceptions when dealing with COM, otherwise I just just use a Generic System.Exception or nothing at all. – Noah May 22 '09 at 18:50
  • This may also be somewhat helpful in describing the entire exception process http://msdn.microsoft.com/en-us/library/6kzk0czb.aspx – Noah May 22 '09 at 18:52
  • Hmm... that still suggests using Exception should just catch everything. http://msdn.microsoft.com/en-us/library/9ztbc5s1.aspx describes how interop maps from HRESULTs to .net exceptions. Note there's no such thing as a COM exception: the runtime creates an Exception when an HRESULT indicates a problem. Well-known HRESULTs are mapped to specific Exception types, everything else results in a COMException. However, I know various crazy things do happen with interop so wouldn't be hugely surprised if something wacky like this did happen, but it would surely have to be regarded as a bug. – Rory May 22 '09 at 19:41
  • It could be a weird AutoCAD interop thing as well, I just kept getting COM errors that would crash AutoCAD until I started using their runtime Exception Class. – Noah May 22 '09 at 20:06
  • OK this is weird. i just had the issue of Exception not catching ComException. Very Weird – Simon Dec 03 '09 at 05:27
3

There's three reasons:

  1. There's a bug in the runtime
  2. The application and/or thread is ending as part of some of the code that executes
  3. You're not seeing the whole picture

Personally I vote for 3, and I have had countless debugging sessions where I wonder why some piece of code isn't handling my exceptions, when in fact it was Visual Studio that was configured to stop on all thrown exceptions, regardless of whether they was caught or not.

Have you tried just asking the program to continue running in the debugger and see if it then ends up in the catch-block?

Also, check the setting in Visual Studio, go to the Debug->Exceptions dialog, and check if you got any of the Thrown checkboxes checked. If you have, that might be your problem.

Of course, if you see this problem at runtime, no debugger attached, then I have no idea, except for point 1 and 2 above.

And of course there's always point 4: The unknown.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
2

A COMException thrown from within that try block will be caught and swallowed by the catch block.

Take a break, get yourself a coffee, put a breakpoint on the line "Logger.Error..." and try again.

Joe
  • 122,218
  • 32
  • 205
  • 338
2

Along COMException there are also asynchronus exceptions that DON'T get caught such as :

  • OutOfMemoryException
  • StackoverflowException (no, it's not a joke related to this site :) )
  • ThreadAbortException

Are you sure that's not the case?

Andrei Rînea
  • 20,288
  • 17
  • 117
  • 166
  • 1
    FYI, you *can* catch OutOfMemoryException. Whether you can successfully free up some memory at that time (release references to things) depends on your application. – Curt Nichols Jul 27 '09 at 21:47
  • Well yes, you technically can catch them but they will be rethrown by the CLR runtime once you exit the catch block on and on.. – Andrei Rînea Jul 28 '09 at 07:35
1

I had a similar problem. I was invoking a VB6 COM object that raised an error. The actual exception type turned out to be System.Reflection.TargetInvocationException. The innerException was set to the COMException. I ended up catching the System.Reflection.TargetInvocationException and checking the innerException