Read message from std::exception into script exception

Started by
10 comments, last by WitchLord 6 years ago

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.

Advertisement

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!)

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.

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());
  }
}

 

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

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.

 

 

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

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

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 :))    

 

 

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

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. 

This topic is closed to new replies.

Advertisement