Question regarding JS_SetErrorReporter

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Question regarding JS_SetErrorReporter

Paul Asmuth
Hey,

I am trying to retrieve the error message after a failed call to the
SpiderMonkey C++ API (e.g. after JS::Evaluate returned false).

The user guide says:

    "The context: Use JS_NewContext and JS_DestroyContext. [...] Error
reporting is also per-context and is enabled using JS_SetErrorReporter.

https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide


But the documentation for JS_SetErrorReporter is inconsistent (note
JSRuntime* vs JSContext* for the first argument):

    JS_SetErrorReporter(JSRuntime *rt, JSErrorReporter er);

    cx     JSContext *       Pointer to a JS context whose errors should be
reported via your function. Other contexts in the same runtime can have
their own error reporting functions.
    er     JSErrorReporter     The user-defined error reporting function to
use in your application, described below.


https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_SetErrorReporter

The version that takes a JSRuntime* as the first argument seems to be the
correct one. In SpiderMonkey 38, jsapi.h I found:

    4425 JS_SetErrorReporter(JSRuntime* rt, JSErrorReporter er);

I am wondering if there is still any method to get per-context error
reporting? Specifically, my questions are:

  - Is it still possible to set a JSErrorReporter for one JSContext only?
  - If not, can I store a userdata pointer in the JSContext? That way I
could set a global JSErrorReporter on the runtime and then dispatch the
errors to the individual contexts myself
  - Or is there any way to access the most recent error in a JSContext?

Background: My application takes a HTTP request with some JavaScript and
executes it using SpiderMonkey, creating a new JSContext for each incoming
request. Maybe that's not the correct approach and I should create a new
JSRuntime for each request? Anyhow with the current setup I need some way
to get the error message back to the HTTPRequest that created the JSContext
in the first place.

many thanks in advance
  ~ paul

--
Paul Asmuth
M: +44-(0)7827-808651
[hidden email]

45 Comeragh Rd.
W149HT London
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: Question regarding JS_SetErrorReporter

Paul Asmuth
In case anybody else is wondering about this, here is how I solved it for now:

  - Create a new JSRuntime for each incoming request since error reporting seems
    to be per-runtime in SpiderMonkey 38 (not per-context as the documentation says)

  - In the code I found that the JSRuntime class has a publicly accessible "opaque
    user data pointer" (JSRuntime->data) that I use to store a pointer back to
    my request. The pointer can be retrieved and modified using
    JS_{Get,Set}RuntimePrivate

  - Finally, I set an error callback on the JSRuntime using JS_SetErrorReporter.
    The error callback will retrieve the JSContext as the first argument so I can
    first retrieve the runtime from the context using JS_GetRuntime and then
    retrieve the the pointer to my original request using JS_GetRuntimePrivate.

Example code with error handling omitted:

    class MyRequest {
    public:

      void execute() {
        auto rt = JS_NewRuntime(memlimit);
        JS_SetRuntimePrivate(rt, this);
        JS_SetErrorReporter(rt, &MyRequest::dispatchError);
        // execute JS
      }

      void onError(const std::string& error) {
        // handle error
      }

      static void dispatchError(
          JSContext* ctx,
          const char* message,
          JSErrorReport* report) {
        auto rt = JS_GetRuntime(ctx);
        auto rt_userdata = JS_GetRuntimePrivate(rt);
        if (rt_userdata) {
          auto req = static_cast<MyRequest*>(rt_userdata);
          req->onError(message);
        }
      }

    };


On Thursday, October 22, 2015 at 11:46:13 AM UTC+2, Paul Asmuth wrote:

> Hey,
>
> I am trying to retrieve the error message after a failed call to the
> SpiderMonkey C++ API (e.g. after JS::Evaluate returned false).
>
> The user guide says:
>
>     "The context: Use JS_NewContext and JS_DestroyContext. [...] Error
> reporting is also per-context and is enabled using JS_SetErrorReporter.
>
> https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide
>
>
> But the documentation for JS_SetErrorReporter is inconsistent (note
> JSRuntime* vs JSContext* for the first argument):
>
>     JS_SetErrorReporter(JSRuntime *rt, JSErrorReporter er);
>
>     cx     JSContext *       Pointer to a JS context whose errors should be
> reported via your function. Other contexts in the same runtime can have
> their own error reporting functions.
>     er     JSErrorReporter     The user-defined error reporting function to
> use in your application, described below.
>
>
> https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_SetErrorReporter
>
> The version that takes a JSRuntime* as the first argument seems to be the
> correct one. In SpiderMonkey 38, jsapi.h I found:
>
>     4425 JS_SetErrorReporter(JSRuntime* rt, JSErrorReporter er);
>
> I am wondering if there is still any method to get per-context error
> reporting? Specifically, my questions are:
>
>   - Is it still possible to set a JSErrorReporter for one JSContext only?
>   - If not, can I store a userdata pointer in the JSContext? That way I
> could set a global JSErrorReporter on the runtime and then dispatch the
> errors to the individual contexts myself
>   - Or is there any way to access the most recent error in a JSContext?
>
> Background: My application takes a HTTP request with some JavaScript and
> executes it using SpiderMonkey, creating a new JSContext for each incoming
> request. Maybe that's not the correct approach and I should create a new
> JSRuntime for each request? Anyhow with the current setup I need some way
> to get the error message back to the HTTPRequest that created the JSContext
> in the first place.
>
> many thanks in advance
>   ~ paul
>
> --
> Paul Asmuth
> M: +44-(0)7827-808651
> [hidden email]
>
> 45 Comeragh Rd.
> W149HT London
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: Question regarding JS_SetErrorReporter

Paul Asmuth
FYI I took the liberty of updating the documentation on JS_SetErrorReporter. Please correct/rollback if my understanding is wrong.

https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_SetErrorReporter$compare?from=711787&to=938569

On Thursday, October 22, 2015 at 3:39:45 PM UTC+2, [hidden email] wrote:

> In case anybody else is wondering about this, here is how I solved it for now:
>
>   - Create a new JSRuntime for each incoming request since error reporting seems
>     to be per-runtime in SpiderMonkey 38 (not per-context as the documentation says)
>
>   - In the code I found that the JSRuntime class has a publicly accessible "opaque
>     user data pointer" (JSRuntime->data) that I use to store a pointer back to
>     my request. The pointer can be retrieved and modified using
>     JS_{Get,Set}RuntimePrivate
>
>   - Finally, I set an error callback on the JSRuntime using JS_SetErrorReporter.
>     The error callback will retrieve the JSContext as the first argument so I can
>     first retrieve the runtime from the context using JS_GetRuntime and then
>     retrieve the the pointer to my original request using JS_GetRuntimePrivate.
>
> Example code with error handling omitted:
>
>     class MyRequest {
>     public:
>
>       void execute() {
>         auto rt = JS_NewRuntime(memlimit);
>         JS_SetRuntimePrivate(rt, this);
>         JS_SetErrorReporter(rt, &MyRequest::dispatchError);
>         // execute JS
>       }
>
>       void onError(const std::string& error) {
>         // handle error
>       }
>
>       static void dispatchError(
>           JSContext* ctx,
>           const char* message,
>           JSErrorReport* report) {
>         auto rt = JS_GetRuntime(ctx);
>         auto rt_userdata = JS_GetRuntimePrivate(rt);
>         if (rt_userdata) {
>           auto req = static_cast<MyRequest*>(rt_userdata);
>           req->onError(message);
>         }
>       }
>
>     };
>
>
> On Thursday, October 22, 2015 at 11:46:13 AM UTC+2, Paul Asmuth wrote:
> > Hey,
> >
> > I am trying to retrieve the error message after a failed call to the
> > SpiderMonkey C++ API (e.g. after JS::Evaluate returned false).
> >
> > The user guide says:
> >
> >     "The context: Use JS_NewContext and JS_DestroyContext. [...] Error
> > reporting is also per-context and is enabled using JS_SetErrorReporter.
> >
> > https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide
> >
> >
> > But the documentation for JS_SetErrorReporter is inconsistent (note
> > JSRuntime* vs JSContext* for the first argument):
> >
> >     JS_SetErrorReporter(JSRuntime *rt, JSErrorReporter er);
> >
> >     cx     JSContext *       Pointer to a JS context whose errors should be
> > reported via your function. Other contexts in the same runtime can have
> > their own error reporting functions.
> >     er     JSErrorReporter     The user-defined error reporting function to
> > use in your application, described below.
> >
> >
> > https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_SetErrorReporter
> >
> > The version that takes a JSRuntime* as the first argument seems to be the
> > correct one. In SpiderMonkey 38, jsapi.h I found:
> >
> >     4425 JS_SetErrorReporter(JSRuntime* rt, JSErrorReporter er);
> >
> > I am wondering if there is still any method to get per-context error
> > reporting? Specifically, my questions are:
> >
> >   - Is it still possible to set a JSErrorReporter for one JSContext only?
> >   - If not, can I store a userdata pointer in the JSContext? That way I
> > could set a global JSErrorReporter on the runtime and then dispatch the
> > errors to the individual contexts myself
> >   - Or is there any way to access the most recent error in a JSContext?
> >
> > Background: My application takes a HTTP request with some JavaScript and
> > executes it using SpiderMonkey, creating a new JSContext for each incoming
> > request. Maybe that's not the correct approach and I should create a new
> > JSRuntime for each request? Anyhow with the current setup I need some way
> > to get the error message back to the HTTPRequest that created the JSContext
> > in the first place.
> >
> > many thanks in advance
> >   ~ paul
> >
> > --
> > Paul Asmuth
> > M: +44-(0)7827-808651
> > [hidden email]
> >
> > 45 Comeragh Rd.
> > W149HT London
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine
Reply | Threaded
Open this post in threaded view
|

Re: Question regarding JS_SetErrorReporter

Terrence Cole-3
I believe that you are correct! Error reporting has, until recently, been
the unloved stepchild of SpiderMonkey's API -- it was accreted more than
designed and then it had exceptions tacked on haphazardly back in the ABI
stable days. We've been slowly cleaning it up, but we can't really make
aggressive changes to it because gecko is in the same straits. It's a giant
mess. In theory, it is /supposed/ to still work with multiple JSContexts,
but I guess maybe gecko only uses a single JSContext mostly now, so maybe
that's regressed?

In either case, you're certainly correct moving to multiple JSRuntimes:
JSContext is slowly going the way of the dodo and serves almost entirely as
a thing to call JS_GetRuntime on now.

On Thu, Oct 22, 2015 at 6:49 AM, <[hidden email]> wrote:

> FYI I took the liberty of updating the documentation on
> JS_SetErrorReporter. Please correct/rollback if my understanding is wrong.
>
>
> https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_SetErrorReporter$compare?from=711787&to=938569
>
> On Thursday, October 22, 2015 at 3:39:45 PM UTC+2, [hidden email]
> wrote:
> > In case anybody else is wondering about this, here is how I solved it
> for now:
> >
> >   - Create a new JSRuntime for each incoming request since error
> reporting seems
> >     to be per-runtime in SpiderMonkey 38 (not per-context as the
> documentation says)
> >
> >   - In the code I found that the JSRuntime class has a publicly
> accessible "opaque
> >     user data pointer" (JSRuntime->data) that I use to store a pointer
> back to
> >     my request. The pointer can be retrieved and modified using
> >     JS_{Get,Set}RuntimePrivate
> >
> >   - Finally, I set an error callback on the JSRuntime using
> JS_SetErrorReporter.
> >     The error callback will retrieve the JSContext as the first argument
> so I can
> >     first retrieve the runtime from the context using JS_GetRuntime and
> then
> >     retrieve the the pointer to my original request using
> JS_GetRuntimePrivate.
> >
> > Example code with error handling omitted:
> >
> >     class MyRequest {
> >     public:
> >
> >       void execute() {
> >         auto rt = JS_NewRuntime(memlimit);
> >         JS_SetRuntimePrivate(rt, this);
> >         JS_SetErrorReporter(rt, &MyRequest::dispatchError);
> >         // execute JS
> >       }
> >
> >       void onError(const std::string& error) {
> >         // handle error
> >       }
> >
> >       static void dispatchError(
> >           JSContext* ctx,
> >           const char* message,
> >           JSErrorReport* report) {
> >         auto rt = JS_GetRuntime(ctx);
> >         auto rt_userdata = JS_GetRuntimePrivate(rt);
> >         if (rt_userdata) {
> >           auto req = static_cast<MyRequest*>(rt_userdata);
> >           req->onError(message);
> >         }
> >       }
> >
> >     };
> >
> >
> > On Thursday, October 22, 2015 at 11:46:13 AM UTC+2, Paul Asmuth wrote:
> > > Hey,
> > >
> > > I am trying to retrieve the error message after a failed call to the
> > > SpiderMonkey C++ API (e.g. after JS::Evaluate returned false).
> > >
> > > The user guide says:
> > >
> > >     "The context: Use JS_NewContext and JS_DestroyContext. [...] Error
> > > reporting is also per-context and is enabled using JS_SetErrorReporter.
> > >
> > >
> https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_User_Guide
> > >
> > >
> > > But the documentation for JS_SetErrorReporter is inconsistent (note
> > > JSRuntime* vs JSContext* for the first argument):
> > >
> > >     JS_SetErrorReporter(JSRuntime *rt, JSErrorReporter er);
> > >
> > >     cx     JSContext *       Pointer to a JS context whose errors
> should be
> > > reported via your function. Other contexts in the same runtime can have
> > > their own error reporting functions.
> > >     er     JSErrorReporter     The user-defined error reporting
> function to
> > > use in your application, described below.
> > >
> > >
> > >
> https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference/JS_SetErrorReporter
> > >
> > > The version that takes a JSRuntime* as the first argument seems to be
> the
> > > correct one. In SpiderMonkey 38, jsapi.h I found:
> > >
> > >     4425 JS_SetErrorReporter(JSRuntime* rt, JSErrorReporter er);
> > >
> > > I am wondering if there is still any method to get per-context error
> > > reporting? Specifically, my questions are:
> > >
> > >   - Is it still possible to set a JSErrorReporter for one JSContext
> only?
> > >   - If not, can I store a userdata pointer in the JSContext? That way I
> > > could set a global JSErrorReporter on the runtime and then dispatch the
> > > errors to the individual contexts myself
> > >   - Or is there any way to access the most recent error in a JSContext?
> > >
> > > Background: My application takes a HTTP request with some JavaScript
> and
> > > executes it using SpiderMonkey, creating a new JSContext for each
> incoming
> > > request. Maybe that's not the correct approach and I should create a
> new
> > > JSRuntime for each request? Anyhow with the current setup I need some
> way
> > > to get the error message back to the HTTPRequest that created the
> JSContext
> > > in the first place.
> > >
> > > many thanks in advance
> > >   ~ paul
> > >
> > > --
> > > Paul Asmuth
> > > M: +44-(0)7827-808651
> > > [hidden email]
> > >
> > > 45 Comeragh Rd.
> > > W149HT London
> _______________________________________________
> dev-tech-js-engine mailing list
> [hidden email]
> https://lists.mozilla.org/listinfo/dev-tech-js-engine
>
_______________________________________________
dev-tech-js-engine mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-tech-js-engine