External nodejs bad request exception

Hi there,

I posted on here with some help for a nodejs external task. This was working ok.

I’ve moved on since then and changed to the tomcat docker image (camunda/camunda-bpm-platform tomcat-7.13.0) and haven’t tested this bit for a while.
The script hasn’t changed but I am getting this error following the nodejs subscription:

✓ subscribed to topic email-document-reminder
:heavy_multiplication_x: polling failed with EngineError: Response code 400 (Bad Request); Error: {“type”:“BadRequestException”,“message”:“RESTEASY003320: Failed processing arguments of public void org.camunda.bpm.engine.rest.impl.FetchAndLockRestServiceImpl.fetchAndLock(org.camunda.bpm.engine.rest.dto.externaltask.FetchExternalTasksExtendedDto,javax.ws.rs.container.AsyncResponse)”}; Type: undefined

I’m a bit confused whats going on. Here is the script, I’ve removed any business logic to remove any possible interference;

const { Client, logger } = require("camunda-external-task-client-js");

// configuration for the Client:

//  - 'baseUrl': url to the Workflow Engine

//  - 'logger': utility to automatically log important events

const config = { baseUrl: "http://localhost:9080/engine-rest", use: logger };

// create a Client instance with custom configuration

const client = new Client(config);

// susbscribe to the topic: 'creditScoreChecker'

client.subscribe("email-document-reminder", async function({ task, taskService }) {

  // Put your business logic

  // complete the task

  await taskService.complete(task);

}); 

Any help would be much appreciated.
Thanks,
Rob

are there any errors appearing in the engine logs?

Hi @Niall,

This is the error from the catalina log:

29-Sep-2020 08:55:26.836 WARNING [http-nio-8080-exec-8] org.apache.catalina.connector.Request.startAsync Unable to start async because the following classes in the processing chain do not support async [org.apache.catalina.filters.CorsFilter]

*** java.lang.IllegalStateException: A filter or servlet of the current chain does not support asynchronous operations.***

So CORS is breaking it. Any ideas what I need to update. This is the current CORS setup on Tomcat:

 <filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>
  <init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>false</param-value>
  </init-param>
  <init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
  </init-param>
</filter>

For testing I’ve set it as “*” for the allowed origins.

Thanks,
Rob

Hi there,

Digging further I noticed there was an additional filter under this section which referred to CorsFilter. I commented it out and now it seems to work as expected:

<!-- <filter-mapping>

  <filter-name>CorsFilter</filter-name>

  <url-pattern>/*</url-pattern>

</filter-mapping> -->

Thanks,
Rob

1 Like

So removing this allowed my NodeJS script to poll the server correctly.

However, now access from my frontend Angular app to the API is being blocked by CORS. The Tomcat docs suggest adding in the filtermapping elements. Seems like I’m a little stuck between 2 different requirements.

Anyone have any suggestions?

So I had to explicitly tell Tomcat that the CorsFilter supported async. Who knew!
As you can tell, not worked a lot with Tomcat but I’ve got there now.

My frontend is allowed to access the API through Cors and my NodeJS script is polling correctly on the topic for the service task.

For anyone that’s interested this is the full excerpt from web.xml. Be aware you should set this up correctly for production use. This is currently allowing all domains via * on the allowed origins list.

<filter>

  <filter-name>CorsFilter</filter-name>

  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>

  <async-supported>true</async-supported>

  <init-param>

    <param-name>cors.allowed.origins</param-name>

    <param-value>*</param-value>

  </init-param>

  <init-param>

    <param-name>cors.allowed.methods</param-name>

    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>

  </init-param>

  <init-param>

    <param-name>cors.allowed.headers</param-name>

    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>

  </init-param>

  <init-param>

    <param-name>cors.exposed.headers</param-name>

    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>

  </init-param>

  <init-param>

    <param-name>cors.support.credentials</param-name>

    <param-value>false</param-value>

  </init-param>

  <init-param>

    <param-name>cors.preflight.maxage</param-name>

    <param-value>10</param-value>

  </init-param>

</filter>

<filter-mapping>

  <filter-name>CorsFilter</filter-name>

  <url-pattern>/*</url-pattern>

</filter-mapping>

Many thanks,
Rob

2 Likes

Thanks a lot for posting the solution you found!