Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is .NET exception not caught by try/catch block?

People also ask

Which exception Cannot be caught in catch block?

Starting with the . NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. ThreadAbortException can be caught, but will always get re-raised, so has unique behavior.

Why are exceptions not caught?

Checked exceptions must be considered at compile time, whereas unchecked exceptions are not. Exception (uppercase E) and it's subclasses are checked exceptions, which means you either have to catch any exception that can be thrown by your code, or declare the exceptions that your method could throw (if not caught).

What happens when a raised exception is not caught by catch block?

What happens if an exception is not caught? If an exception is not caught (with a catch block), the runtime system will abort the program (i.e. crash) and an exception message will print to the console.

Will the exception will be caught properly in the try catch block?

try – A try block is used to encapsulate a region of code. If any code throws an exception within that try block, the exception will be handled by the corresponding catch. catch – When an exception occurs, the Catch block of code is executed. This is where you are able to handle the exception, log it, or ignore it.


I believe I understand the problem. The exception is being caught, the issue is confusion over the debugger's behavior and differences in the debugger settings among each person trying to repro it.

In the 3rd case from your repro I believe you are getting the following message: "NoViableAltException was unhandled by user code" and a callstack that looks like this:

         [External Code]    
    >   TestAntlr-3.1.exe!TimeDefLexer.mTokens() Line 852 + 0xe bytes   C#
        [External Code] 
        TestAntlr-3.1.exe!TimeDefParser.prog() Line 141 + 0x14 bytes    C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.ParseTest(string Text = "foobar;") Line 49 + 0x9 bytes C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.Main(string[] args = {string[0x00000000]}) Line 30 + 0xb bytes C#
        [External Code] 

If you right click in the callstack window and run turn on show external code you see this:

        Antlr3.Runtime.dll!Antlr.Runtime.DFA.NoViableAlt(int s = 0x00000000, Antlr.Runtime.IIntStream input = {Antlr.Runtime.ANTLRStringStream}) + 0x80 bytes   
        Antlr3.Runtime.dll!Antlr.Runtime.DFA.Predict(Antlr.Runtime.IIntStream input = {Antlr.Runtime.ANTLRStringStream}) + 0x21e bytes  
    >   TestAntlr-3.1.exe!TimeDefLexer.mTokens() Line 852 + 0xe bytes   C#
        Antlr3.Runtime.dll!Antlr.Runtime.Lexer.NextToken() + 0xc4 bytes 
        Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.FillBuffer() + 0x147 bytes   
        Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.LT(int k = 0x00000001) + 0x2d bytes  
        TestAntlr-3.1.exe!TimeDefParser.prog() Line 141 + 0x14 bytes    C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.ParseTest(string Text = "foobar;") Line 49 + 0x9 bytes C#
        TestAntlr-3.1.exe!TestAntlr_3._1.Program.Main(string[] args = {string[0x00000000]}) Line 30 + 0xb bytes C#
        [Native to Managed Transition]  
        [Managed to Native Transition]  
        mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x39 bytes    
        Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes  
        mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x3b bytes   
        mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x81 bytes    
        mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 bytes

The debugger's message is telling you that an exception originating outside your code (from NoViableAlt) is going through code you own in TestAntlr-3.1.exe!TimeDefLexer.mTokens() without being handled.

The wording is confusing, but it does not mean the exception is uncaught. The debugger is letting you know that code you own mTokens()" needs to be robust against this exception being thrown through it.

Things to play with to see how this looks for those who didn't repro the problem:

  • Go to Tools/Options/Debugging and turn off "Enable Just My code (Managed only)". or option.
  • Go to Debugger/Exceptions and turn off "User-unhandled" for Common-Language Runtime Exceptions.

Regardless of whether the assembly has been compiled as a release build the exception should certainly 'bubble' up to the caller, there's no reason an assembly not being compiled in debug mode should have any affect on that.

I'd agree with Daniel is suggesting that perhaps the exception is occurring on a separate thread - try hooking the thread exception event in Application.ThreadException. This should be raised when any unhandled thread exception occurs. You could adapt your code thus:-

using System.Threading;

...

void Application_ThreadException(object sender, ThreadExceptionEventArgs e) {
  throw new ParserException(e.Exception.Message, e.Exception);
}    

 ...

 var exceptionHandler = 
    new ThreadExceptionEventHandler(Application_ThreadException);
 Application.ThreadException += exceptionHandler;
 try {
    // Execution stopped at parser.prog()
    TimeDefParser.prog_return prog_ret = parser.prog();
    return prog_ret == null ? null : prog_ret.value;
 }
 catch (Exception ex) {
    throw new ParserException(ex.Message, ex);
 }
 finally {
    Application.ThreadException -= exceptionHandler;
 }

I can tell you what's happening here...

Visual Studio is breaking because it thinks the exception is unhandled. What does unhandled mean? Well, in Visual Studio, there is a setting in the Tools... Options... Debugging... General... "Enable Just My Code (Managed only)". If this is checked and if the exception propagates out of your code and out to a stack frame associated with a method call that exists in an assembly which is "NOT YOUR CODE" (for example, Antlr), that is considered "unhandled". I turn off that Enable Just My Code feature for this reason. But, if you ask me, this is lame... let's say you do this:

ExternalClassNotMyCode c = new ExternalClassNotMyCode();
try {
    c.doSomething( () => { throw new Exception(); } );
}
catch ( Exception ex ) {}

doSomething calls your anonymous function there and that function throws an exception...

Note that this is an "unhandled exception" according to Visual Studio if "Enable Just My Code" is on. Also, note that it stops as if it were a breakpoint when in debug mode, but in a non-debugging or production environment, the code is perfectly valid and works as expected. Also, if you just "continue" in the debugger, the app goes on it's merry way (it doesn't stop the thread). It is considered "unhandled" because the exception propagates through a stack frame that is NOT in your code (i.e. in the external library). If you ask me, this is lousy. Please change this default behavior Microsoft. This is a perfectly valid case of using Exceptions to control program logic. Sometimes, you can't change the third party library to behave any other way, and this is a very useful way to accomplish many tasks.

Take MyBatis for example, you can use this technique to stop processing records that are being collected by a call to SqlMapper.QueryWithRowDelegate.


Are you using .Net 1.0 or 1.1? If so then catch(Exception ex) won't catch exceptions from unmanaged code. You'll need to use catch {} instead. See this article for further details:

http://www.netfxharmonics.com/2005/10/net-20-trycatch-and-trycatchexception/


I'm with @Shaun Austin - try wrapping the try with the fully qualified name

catch (System.Exception)

and see if that helps.Does the ANTLR doc say what Exceptions should be thrown?


Is it possible that the exception is being thrown in another thread? Obviously your calling code is single threaded, but maybe the library you are consuming is doing some multithreaded operations under the covers.


To me, a catch (Exception) clause should've captured any exception whatsoever. Is there any reason why it wouldn't?

The only possibility I can think of is that something else is catching it before you and handling it in a way that appears to be an uncaught exception (e.g. exiting the process).

my try/catch block won't catch it and instead stops execution as an unhandled exception.

You need to find what is causing the exit process. It might be something other than an unhandled exception. You might try using the native debugger with a breakpoint set on "{,,kernel32.dll}ExitProcess". Then use SOS to determine what managed code is calling exit process.