locked
[C++/Cx] When exception is being thrown it can not be caught by catch clause, instead it is being handled by __abi_FailFast() RRS feed

  • Question

  • Hi,

    I've found a problem in catching exceptions in C++/Cx code. Below code show the problem.

    TestClass1 can catch the exception without problems.

    TestClass2 cannot catch the exception and the exception is being handled by __abi_FailFast()

    namespace ExceptionThrowingTestComp
    {
    //----------------------------------------------------------------------------------------------------------------
    namespace WPGI = Windows::Phone::Graphics::Interop;
    namespace WFM = Windows::Foundation::Metadata;
    //----------------------------------------------------------------------------------------------------------------
    [WFM::WebHostHidden]
    public interface class IReq
    {
    public:
    	virtual void Perform();
    };
    //----------------------------------------------------------------------------------------------------------------
    [WFM::WebHostHidden]
    public ref class TestRequest sealed : public IReq
    {
    public:
    	virtual void Perform()
    	{
    		throw std::exception("msg");
    	}
    };
    //----------------------------------------------------------------------------------------------------------------
    [WFM::WebHostHidden]
    public ref class TestClass1 sealed
    {
    public:
    	TestClass1()
    	{
    		auto&& testRequest = ref new TestRequest();
    
    		handleRequest(testRequest);
    	}
    
    	void handleRequest(TestRequest^ t)
    	{
    		try
    		{
    			t->Perform();
    		}
    		catch(...)
    		{
    			// SUCCESS! exception can be caught here
    		}
    	}
    };
    //----------------------------------------------------------------------------------------------------------------
    [WFM::WebHostHidden]
    public ref class TestClass2 sealed
    {
    public:
    	TestClass2()
    	{
    		auto&& testRequest = ref new TestRequest();
    
    		handleRequest(testRequest);
    	}
    
    	void handleRequest(IReq^ request)
    	{
    		try
    		{
    			request->Perform();
    		}
    		catch(...)
    		{
    			// FAILURE! never enters here
    		}
    	}
    };
    }

    After digging throug internet I've found that guys from Mozzilla also ecauntered this problem:

    https://bugzilla.mozilla.org/show_bug.cgi?id=775378

    Any ideas what to do with this?



    • Edited by kmne Tuesday, January 28, 2014 2:01 PM
    Tuesday, January 28, 2014 1:58 PM

Answers

  • public ref class TestRequest sealed : public IReq
    {
    public:
    	virtual void Perform()
    	{
    		throw ref new Platform::Exception(0x80041008);
    	}
    };

    You will get a first chance exception raised in the debugger. You can ignore this and continue. The catch block should be executed as expected. I confirmed this on Windows 8 but the code is the same for the phone.


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/


    Thursday, January 30, 2014 1:22 AM
  • Hello,

    I know this looks very strange but this behavior is actually by design. When we have a reference to an interface we actually try to lookup the exception code and translate that to an HRESULT. If no HRESULT is found we assume this is a mistake and call __abi_FailFast. Theoretically if you set the exception information properly you should not see this call.

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Wednesday, January 29, 2014 2:14 AM

All replies

  • Hello,

    I know this looks very strange but this behavior is actually by design. When we have a reference to an interface we actually try to lookup the exception code and translate that to an HRESULT. If no HRESULT is found we assume this is a mistake and call __abi_FailFast. Theoretically if you set the exception information properly you should not see this call.

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Wednesday, January 29, 2014 2:14 AM
  • Hi,

    Thanks for the answer.

    Theoretically if you set the exception information properly you should not see this call.


    What do You mean by "set the exception information properly"? How can I do this? Should I throw for example more concrete exception like std::invalid_argument instead of generic std::exception? That doesn't work either.

    You've mentioned that if no HRESULT is found the _abi_FailFast is being called. If I throw Platform::InvalidArgumentException which contains properly set HRESULT it's still being handled by _abi_FailFast.

    I'm very grateful for your support, but could you elaborate a bit more on this subject?

    Wednesday, January 29, 2014 8:19 AM
  • public ref class TestRequest sealed : public IReq
    {
    public:
    	virtual void Perform()
    	{
    		throw ref new Platform::Exception(0x80041008);
    	}
    };

    You will get a first chance exception raised in the debugger. You can ignore this and continue. The catch block should be executed as expected. I confirmed this on Windows 8 but the code is the same for the phone.


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/


    Thursday, January 30, 2014 1:22 AM