Membrane API Gateway returns 500 Internal Server Error with the title Error executing script. when a script in the javascript plugin throws an error while it runs. The script is part of the gateway configuration, so it is usually to blame, sometimes together with a message whose body is not in the form the script expects.
The response contains the status 500 Internal Server Error, the title Error executing script., the problem type https://membrane-api.io/problems/internal and a link to this page. In development mode it also contains the script as source, the position of the error as line and column, and the engine that ran the script (rhino or graal). The type internal means that the gateway could not complete the processing of the exchange. In production mode, the title is replaced by Internal Server Error and the details are left out.
The javascript plugin runs a script in the request or response flow. Membrane uses the GraalVM JavaScript engine when it is available and falls back to Rhino otherwise. The script can read and change the message through variables such as message, header, params and json. See the JavaScript plugin page for the available variables. If the script throws, Membrane stops the flow and answers with this error.
An undefined variable leads to a ReferenceError, a property access on undefined or null to a TypeError. An explicit throw in the script ends up here as well.
The json variable is only set when the message body can be parsed as JSON. If the body is empty or not valid JSON, the variable does not exist, and every access to it fails. With Rhino, a message that is marked as JSON but has an invalid body already fails while Membrane parses the body before the script runs.
Objects such as message, Request or Response are Java objects. Calling one of their methods with arguments of the wrong type or number throws an error.
Any other exception that the javascript plugin does not turn into an error response itself is reported under the same URL by Membrane's generic error handler. The detail then reads Aborting! Exception caused in … flow. and names the plugin, the request URI and the flow. Unless the exception points to your configuration or to the message, this usually indicates a bug in Membrane.
line, column and message from the response (development mode), or the log entry Error executing javascript script, to find the failing statement.json exists and has the properties you need before you use them.Content-Type.The following script only reads json.name when the body is JSON and has that property:
api:
port: 2000
flow:
- request:
- javascript:
src: |
var name = (typeof json !== 'undefined' && json && json.name) ? json.name : 'unknown';
message.getHeader().setValue('X-Name', name);
CONTINUE
target:
url: https://api.predic8.de
api:
port: 2000
flow:
- request:
- javascript:
src: |
var name = (typeof json !== 'undefined' && json && json.name) ? json.name : 'unknown';
message.getHeader().setValue('X-Name', name);
CONTINUE
target:
url: https://api.predic8.de
By default, Membrane runs in development mode and adds details to error responses that help you find the problem. These details may reveal information about your setup. In production, turn them off:
configuration:
production: trueconfiguration: production: true
Add the configuration document to your apis.yaml and separate it from the APIs with ---. The title then reads Internal Server Error, and instead of the details the response only contains a log key. Search the gateway log for this key to find the exception.
If the plugin is nested inside a request, response or abort element and throws an unexpected exception, the exception message, the stack trace and the link to this page are currently sent even in production mode. Fix the failing plugin rather than relying on production mode to hide them.
Configuration reference:
Tutorials with runnable examples:
Still stuck? See the troubleshooting guide or ask on GitHub Issues. For commercial support, contact info@predic8.de.