Jump to content
  • Advertisement
Boost113

Read message from std::exception into script exception

Recommended Posts

I'd like to be able to read the messages from exceptions that AngelScript catches without the hassle of using gdb with break on throw.

So I suggest adding the following code to as_context.cpp before the "catch (...)" part:

catch (const std::exception &e)
{
 	SetExpection((TXT_EXCEPTION_CAUGHT ", with message: " + std::string(e.what()))c._str());
}

This was the only relevant link to this that I found: http://www.angelcode.com/angelscript/sdk/docs/manual/doc_cpp_exceptions.html 

But as almost all of my methods exposed to AngelScripts can throw exceptions it's not really possible (and probably bad for performance) to wrap them in extra wrappers that are there to just catch exception messages.

I'm using Last Changed Rev: 2457 so hopefully this hasn't been done after that.

Share this post


Link to post
Share on other sites
Advertisement

More generally, It would be even better if the AS could support exceptions and interoperate with C++ exception mechanisms. :-D

Share this post


Link to post
Share on other sites

Angelscript doesn't really use STL that extensively, so it doesn't make much sense to me to catch a std::exception. Why not catch/handle some kind of asIException type or so? (Which could then potentially also be implemented into the scripting itself!)

Share this post


Link to post
Share on other sites
Just now, Miss said:

Angelscript doesn't really use STL that extensively, so it doesn't make much sense to me to catch a std::exception. Why not catch/handle some kind of asIException type or so? (Which could then potentially also be implemented into the scripting itself!)

That would not work for me as I extensively use third party libraries that report errors as exceptions, that are derived from std::exception.

I think that this feature will only be useful if the exceptions that the script context can read messages from don't need to derive from or now about AngelScript types.

Share this post


Link to post
Share on other sites
Posted (edited)

Perhaps in that case it would be better to set a callback function on the context for other caught exceptions not of this hypothetical asIException type.

Additionally, if your AS bindings are wrapper functions, you can always catch any exceptions in there and pass them along to the context, eg:

static void ScriptDoSomething()
{
  try {
    SomeLibrary::DoSomething();
  } catch (const std::exception &ex) {
    asGetActiveContext()->SetException(ex.what());
  }
}

 

Edited by Miss

Share this post


Link to post
Share on other sites

You could use C++11 and newer exception support to handle some of this more easily:

http://en.cppreference.com/w/cpp/error/current_exception

http://en.cppreference.com/w/cpp/error/uncaught_exception

http://en.cppreference.com/w/cpp/error/rethrow_exception

More: http://en.cppreference.com/w/cpp/header/exception

 

You can use this to implement a callback to handle the exceptions without needing explicit support in Angelscript's code:

void HandleASException( asIScriptContext* pContext )
{
	if( std::unhandled_exceptions() > 0 )
	{
		try
		{
			std::rethrow_exception( std::current_exception() );
		}
		catch( const std::exception& e )
		{
		}
		catch( const MyException& e )
		{
		}
		catch( ... )
		{
		}
	}
}

(could also be a while ( std::unhandled_exceptions() > 0 ) loop)

So what you need is a per-context or engine-global callback. This can be handled just like the line callback: http://www.angelcode.com/angelscript/sdk/docs/manual/classas_i_script_context.html#ae2747f643bf9a07364f922c460ef57dd

Share this post


Link to post
Share on other sites

I won't be implementing a catch for specific exception types in the core library. Today you're asking for std::exception, tomorrow someone else will ask for another, and so. 

I will however consider allowing applications to do this through a callback. perhaps using what Solokiller suggested, which looks quite nice, or else allow the application to provide a custom exception handling code that would be injected into the angelscript code at compile time with an #include statement.

 

 

Share this post


Link to post
Share on other sites
14 hours ago, WitchLord said:

I won't be implementing a catch for specific exception types in the core library. Today you're asking for std::exception, tomorrow someone else will ask for another, and so. 

I will however consider allowing applications to do this through a callback. perhaps using what Solokiller suggested, which looks quite nice, or else allow the application to provide a custom exception handling code that would be injected into the angelscript code at compile time with an #include statement.

 

 

I was initially going to argue that any self-respecting c++ library will use std::exception as a base type for all of their exceptions. But after cooling down for a while I can definitely see that allowing that might open the gates for requests of other exception types and a generic callback gives more flexibility.

After looking at solokiller's suggestion I decided to attempt to implement such a callback. And I got it working.

I attached a diff of my changes. I basically duplicated what asCContext::SetExceptionCallback does to make a new "Translate exception" callback, which I placed into a new method "HandleExceptionHappened", I had to add this as c++ exceptions were caught in multiple places. So now setting that callback to something like this:

void ScriptTranslateExceptionCallback(asIScriptContext* context, void* userdata)
{
    try {
        std::rethrow_exception(std::current_exception());
    } catch(const std::exception& e) {
        context->SetException(
            (std::string("Caught application exception: ") + e.what()).c_str());
    }
}

ctx->SetTranslateExceptionCallback(asFUNCTION(ScriptTranslateExceptionCallback), nullptr, asCALL_CDECL);

Results in nicer script exception messages: "Caught application exception: Testing custom messages"

 

as_exception_translate.diff

Share this post


Link to post
Share on other sites

Thanks for sharing the code. I'll certainly take advantage of this.

However, before I merge it into the library I'll take some time to study the portability of this code. I'll probably have to use the AS_CAN_USE_CPP11 flag to turn something like this off when AngelScript is used with older compilers that are not C++11 compliant.

Besides, as this changes the interface of the library, I'll only be able to include it in release 2.33.0 (though that doesn't necessarily mean that the next release won't be 2.33.0 :))    

 

 

Share this post


Link to post
Share on other sites
3 hours ago, WitchLord said:

However, before I merge it into the library I'll take some time to study the portability of this code. I'll probably have to use the AS_CAN_USE_CPP11 flag to turn something like this off when AngelScript is used with older compilers that are not C++11 compliant.

I don't think that's completely necessary as (AFAIK) none of the changes I did to AngelScript depend on C++11. But that sample callback needs C++11 to work correctly. So there's probably not much use for the callback without C++11 support, but the library should compile fine, it would just be have an extra useless feature.

3 hours ago, WitchLord said:

Besides, as this changes the interface of the library, I'll only be able to include it in release 2.33.0

I'd like to see this feature added to the svn version as soon as possible as I don't mid switching to a newer revision to use this (I've been using the svn latest branch for a long time now). So when the next actual release doesn't matter that much to me. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!