Skip to content

XMLHttpRequest Post times out #74

Closed
@marcgrue

Description

@marcgrue

When importing

import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._

I get the following timeout problem when doing a XMLHttpRequest Post:

/Users/mg/github/marcgrue/MacrotaskExecutor-post-test/node_modules/jsdom/lib/jsdom/living/helpers/events.js:15
  const event = createAnEvent(e, target._globalObject, eventInterface, attributes);
                                        ^

TypeError: Cannot read properties of undefined (reading '_globalObject')
    at fireAnEvent (/Users/mg/github/marcgrue/MacrotaskExecutor-post-test/node_modules/jsdom/lib/jsdom/living/helpers/events.js:15:41)
    at Timeout._onTimeout (/Users/mg/github/marcgrue/MacrotaskExecutor-post-test/node_modules/jsdom/lib/jsdom/living/post-message.js:36:7)
    at listOnTimeout (node:internal/timers:564:17)
    at process.processTimers (node:internal/timers:507:7)

Node.js v19.3.0

Client code:

// Fails
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._

// Works
//import scala.concurrent.ExecutionContext.Implicits.global

lazy val post: Future[String] = {
  val req     = new dom.XMLHttpRequest()
  val promise = Promise[dom.XMLHttpRequest]()
  req.onreadystatechange = { (_: dom.Event) =>
    if (req.readyState == 4) {
      if ((req.status >= 200 && req.status < 300) || req.status == 304) {
        promise.success(req)
      } else {
        promise.failure(new Exception(req.toString))
      }
    }
  }
  req.open("POST", "http://localhost:8080/post/test")
  req.timeout = 0
  req.setRequestHeader("Content-Type", "application/json")
  req.send()
  promise.future.map(_.response.asInstanceOf[String])
}

lazy val tests = Tests {
  "exception test" - {
    for {
      _ <- post.map(_ ==> "hello world")
    } yield ()
  }
}

Server code:

  implicit val system           = ActorSystem(Behaviors.empty, "actorSystem")
  implicit val executionContext = system.executionContext

  Http()
    .newServerAt("localhost", 8080)
    .bind {
      cors() {
        path("post" / "test").apply {
          post {
            extractRequest { _ =>
              complete("hello world")
            }
          }
        }
      }
    }
    .onComplete {
      case Success(b) => println(s"Ajax server is running ${b.localAddress} ")
      case Failure(e) => println(s"there was an error starting the server $e")
    }

Switching back to the standard import

import scala.concurrent.ExecutionContext.Implicits.global

solves the problem (but creates the other usual problems that is warned about).

Here's a minimal reproduction project with the above code:
https://github.com/marcgrue/MacrotaskExecutor-post-test

Shouldn't the macrotaskExecutor work for this scenario?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions