You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala.js:fastOptJS运行正常但fullOptJS失败,求助排查UndefinedBehaviorError

Why fullOptJS Fails When fastOptJS Works (And How to Fix It)

Hey, this is a super common gotcha with Scala.js builds—fastOptJS keeps things loose for debugging, while fullOptJS cranks up optimization and type strictness to 11. Let's break down why your code is breaking, then fix it.

The Root Cause

  • fastOptJS is your debug-friendly build: it preserves runtime type checks and takes a lenient approach to type casts. When you use asInstanceOf[Boolean] on a dynamic JS value (like the input from swal), it might just return a wonky value instead of throwing an error, letting your code limp along.
  • fullOptJS is your production-ready build: it does aggressive optimizations like inlining functions, stripping dead code, and enforcing strict type assumptions. When you use asInstanceOf[Boolean] on a value that's actually a string (which happens when the user enters text and confirms), Scala.js throws UndefinedBehaviorError because it expects the type to match exactly in optimized mode.

Looking at your code, the input parameter from swal's callback is dynamically typed in JS: it's false (a boolean) when the user cancels, and a string when they enter text. Your direct asInstanceOf[Boolean] works in fastOpt because it's not checking strictly, but fullOpt calls you out on the type mismatch.

Fixes: Safely Handle Dynamic JS Values

Stop relying on asInstanceOf for cross-type casts on JS values. Instead, use Scala.js tools to check types properly.

Option 1: Check Types with js.typeOf

This mirrors JS's own type checking directly:

$("button").on("click", ".showDialog", (event: JQueryEventObject) => {
  event.preventDefault()
  val helpText = "Enter any number"
  js.Dynamic.global.swal(
    js.Dynamic.literal(
      title = helpText,
      text = helpText,
      `type` = "input",
      showCancelButton = true,
      closeOnConfirm = false,
      inputPlaceholder = helpText
    ),
    (input: js.Any) => {
      js.typeOf(input) match {
        case "boolean" =>
          // User clicked cancel—input is false
          js.Dynamic.global.swal("Cancelled", "You bailed out!", "info")
        case "string" =>
          // User entered text—parse it safely
          input.asInstanceOf[String].toIntOption match {
            case Some(validNum) =>
              js.Dynamic.global.swal("Success!", s"Got your number: $validNum", "success")
            case None =>
              js.Dynamic.global.swal("Oops!", "That's not a valid number", "error")
          }
        case _ =>
          js.Dynamic.global.swal("Error!", "Unexpected input type", "error")
      }
    }
  )
})

Option 2: Scala-Style Pattern Matching

Scala.js lets you pattern match on JS values, making the code cleaner and more idiomatic:

(input: js.Any) => input match {
  case false: Boolean =>
    // Handle cancel action
    js.Dynamic.global.swal("Cancelled", "Operation cancelled", "info")
  case inputStr: String if inputStr.trim.nonEmpty =>
    // Process the input string
    inputStr.toIntOption match {
      case Some(num) => js.Dynamic.global.swal("Great!", s"Number received: $num", "success")
      case None => js.Dynamic.global.swal("Whoops!", "Please enter a valid number", "error")
    }
  case _ =>
    // Catch-all for empty input or weird types
    js.Dynamic.global.swal("Error!", "Something went wrong", "error")
}

Pro Tip: Ditch Any for js.Any

Change your callback parameter type from Any to js.Any (or js.Dynamic). This tells Scala.js you're dealing with a native JS value, so type checks and conversions will behave as expected, rather than treating it like a Scala Any type.

How to Verify

After updating your code, run fullOptJS and test the production build. If you still hit issues, you can enable debug mode for fullOpt with the -P scalajs:devMode flag—this keeps more debug info around to help track down any remaining problems.

内容的提问来源于stack exchange,提问作者sergeda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:21:59