I am working with the DASpiderMonkey Scripting Engine and want information about the exceptions that are being raised from the scripting provider. I see you have the ScriptException which raises some information out but I want access to the full JSErrorReport record ( especially the linebuf, tokenptr)
I went ahead and wrote a few helper classes that accessed the private variables. It’s kind of hacky but relatively safe as far as I can tell. I’m posting here if anyone else wants to do the same.
type
TDASpiderMonkeyScriptEngine_Helper = class helper for TDASpiderMonkeyScriptEngine
private
class var EngineOffset: Integer;
function getEngine: TDASpiderMonkeyNativeEngine;
public
class constructor Create; {execute on program start}
property Engine : TDASpiderMonkeyNativeEngine read getEngine;
end;
TDASpiderMonkeyNativeEngine_Helper = class helper for TDASpiderMonkeyNativeEngine
private
class var ErrorOffset: Integer;
function getError: SMErrorReport;
public
class constructor Create; {execute on program start}
property Error : SMErrorReport read getError;
end;
implementation
{$region ' TDASpiderMonkeyScriptEngine_Helper '}
{ TDASpiderMonkeyScriptEngine_Helper }
class constructor TDASpiderMonkeyScriptEngine_Helper.Create;
var
ctx: TRTTIContext;
begin
EngineOffset := ctx.GetType(TDASpiderMonkeyScriptEngine).GetField('FEngine').Offset;
end;
function TDASpiderMonkeyScriptEngine_Helper.getEngine: TDASpiderMonkeyNativeEngine;
begin
Result := TDASpiderMonkeyNativeEngine(Pointer(NativeInt(Self) + EngineOffset)^);
end;
{$endregion}
{$region ' TDASpiderMonkeyNativeEngine_Helper '}
{ TDASpiderMonkeyNativeEngine_Helper }
class constructor TDASpiderMonkeyNativeEngine_Helper.Create;
var
ctx: TRTTIContext;
begin
ErrorOffset := ctx.GetType(TDASpiderMonkeyNativeEngine).GetField('FError').Offset;
end;
function TDASpiderMonkeyNativeEngine_Helper.getError: SMErrorReport;
begin
Result := SMErrorReport(Pointer(NativeInt(Self) + ErrorOffset)^);
end;
{$endregion}
Then to use it I just did something like this…
//fEngine : TDASpiderMonkeyScriptProvider;
try
fEngine.LoadScript('function main(){a := "test";}');
except
on e: ScriptException do begin
raise exception.create(TDASpiderMonkeyScriptEngine(fEngine.Engine).Engine.Error.linebuf);
end;
end;