I'm seeing some weird behavior. I have isolated a ...
# webassembly
k
I'm seeing some weird behavior. I have isolated a reproducer for an exception not being caught in one of my unit tests.
Copy code
@Test fun foo() {
  assertFails {
    1 / 0
  }
}
The thrown
RuntimeError
is not caught. Is this expected? Stacktrace in thread 🧵
Copy code
RuntimeError: divide by zero
      at <alchemist_test>.kotlin.Int__div-impl (<wasm://wasm/><alchemist_test>-004f044e:wasm-function[2105]:0x347ba)
      at <alchemist_test>.io.github.kevincianfarini.alchemist.SaturatingLongTest.dividing_by_double_zero_throws (<wasm://wasm/><alchemist_test>-004f044e:wasm-function[4933]:0x67b62)
      at <alchemist_test>.io.github.kevincianfarini.alchemist.test fun$io.github.kevincianfarini.alchemist test fun$SaturatingLongTest test fun$dividing_by_double_zero_throws test fun.invoke (<wasm://wasm/><alchemist_test>-004f044e:wasm-function[4653]:0x5b3a1)
      at <alchemist_test>.kotlin.test.TeamcityAdapter$test$lambda.invoke (<wasm://wasm/><alchemist_test>-004f044e:wasm-function[4228]:0x57519)
      at <alchemist_test>.kotlin.test.TeamcityAdapterWithPromiseSupport.runOrScheduleNextWithResult (<wasm://wasm/><alchemist_test>-004f044e:wasm-function[4110]:0x55a28)
      at <alchemist_test>.kotlin.test.TeamcityAdapterWithPromiseSupport.runOrScheduleNextWithResult (<wasm://wasm/><alchemist_test>-004f044e:wasm-function[4111]:0x55a66)
      at <alchemist_test>.kotlin.test.TeamcityAdapter.test (<wasm://wasm/><alchemist_test>-004f044e:wasm-function[4251]:0x5908f)
      at <alchemist_test>.kotlin.test.test (<wasm://wasm/><alchemist_test>-004f044e:wasm-function[4254]:0x592aa)
      at <alchemist_test>.io.github.kevincianfarini.alchemist.test fun$io.github.kevincianfarini.alchemist test fun$SaturatingLongTest test fun.invoke (<wasm://wasm/><alchemist_test>-004f044e:wasm-function[4723]:0x5c285)
      at <alchemist_test>.io.github.kevincianfarini.alchemist.test fun$io.github.kevincianfarini.alchemist test fun$SaturatingLongTest test fun.invoke (<wasm://wasm/><alchemist_test>-004f044e:wasm-function[4724]:0x5c2b6)
k
Ooooffff, thanks for calling this out!
s
It is a default Wasm trap, and Wasm can’t catch traps at the moment. Proper exceptions for
/
are not implemented yet in Kotlin compiler.
k
Additionally, do you know why
1 / 0
on JS (not wasmJs) doesn't throw at all?
Copy code
assertFailsWith<ArithmeticException> {
            1.0 / 0.0
        }
output:
Copy code
io.github.kevincianfarini.alchemist.SaturatingLongTest.dividing_by_double_zero_throws[js, node] FAILED
    AssertionError: Expected an exception of class ArithmeticException to be thrown, but was completed successfully.
        at DefaultJsAsserter.protoOf.fail_zdvzi9(/home/kevin/code/alchemist/build/compileSync/js/test/testDevelopmentExecutable/kotlin/js/src/main/kotlin/kotlin/test/JsImpl.kt:23)
        at DefaultJsAsserter.protoOf.fail_o3vfxl(/home/kevin/code/alchemist/build/compileSync/js/test/testDevelopmentExecutable/kotlin/js/src/main/kotlin/kotlin/test/DefaultJsAsserter.kt:71)
        at <global>.checkResultIsFailure(/home/kevin/code/alchemist/build/compileSync/js/test/testDevelopmentExecutable/kotlin/src/kotlin/util/Result.kt:36)
c
beacuse its javascript 😉
1.0/0.0 === Infinity
k
Not for
Long
it isn't! tests:
Copy code
@Test
    fun int_division_by_zero_fails_arithmetic_exception() {
        assertFailsWith<ArithmeticException> {
            1 / 0
        }
    }

    @Test
    fun long_division_by_zero_fails_artithmetic_exception() {
        assertFailsWith<ArithmeticException> {
            1L / 0L
        }
    }
Output:
Copy code
io.github.kevincianfarini.alchemist.SaturatingLongTest.int_division_by_zero_fails_arithmetic_exception[js, node] FAILED
    AssertionError: Expected an exception of class ArithmeticException to be thrown, but was completed successfully.
        at DefaultJsAsserter.protoOf.fail_zdvzi9(/home/kevin/code/alchemist/build/compileSync/js/test/testDevelopmentExecutable/kotlin/js/src/main/kotlin/kotlin/test/JsImpl.kt:23)
        at DefaultJsAsserter.protoOf.fail_o3vfxl(/home/kevin/code/alchemist/build/compileSync/js/test/testDevelopmentExecutable/kotlin/js/src/main/kotlin/kotlin/test/DefaultJsAsserter.kt:71)
        at <global>.checkResultIsFailure(/home/kevin/code/alchemist/build/compileSync/js/test/testDevelopmentExecutable/kotlin/src/kotlin/util/Result.kt:36)
        at SaturatingLongTest.protoOf.int_division_by_zero_fails_arithmetic_exception_de063(/home/kevin/code/alchemist/build/compileSync/js/test/testDevelopmentExecutable/kotlin/common/src/main/kotlin/kotlin/test/Assertions.kt:661)
        at <global>.fn(kotlin/alchemist-test.js:4360)
        at Context.<anonymous>(/home/kevin/code/alchemist/build/js/node_modules/kotlin-web-helpers/src/KotlinTestTeamCityConsoleAdapter.ts:72)
        at <global>.processImmediate(node:internal/timers:478)

io.github.kevincianfarini.alchemist.SaturatingLongTest.long_division_by_zero_fails_artithmetic_exception[js, node] FAILED
    AssertionError: Expected an exception of class ArithmeticException to be thrown, but was Exception: division by zero
        at DefaultJsAsserter.protoOf.fail_zdvzi9(/home/kevin/code/alchemist/build/compileSync/js/test/testDevelopmentExecutable/kotlin/js/src/main/kotlin/kotlin/test/JsImpl.kt:23)
        at <global>.checkResultIsFailure(/home/kevin/code/alchemist/build/compileSync/js/test/testDevelopmentExecutable/kotlin/src/kotlin/util/Result.kt:46)
        at SaturatingLongTest.protoOf.long_division_by_zero_fails_artithmetic_exception_2udkyc(/home/kevin/code/alchemist/build/compileSync/js/test/testDevelopmentExecutable/kotlin/common/src/main/kotlin/kotlin/test/Assertions.kt:661)
        at <global>.fn(kotlin/alchemist-test.js:4365)
        at Context.<anonymous>(/home/kevin/code/alchemist/build/js/node_modules/kotlin-web-helpers/src/KotlinTestTeamCityConsoleAdapter.ts:72)
        at <global>.processImmediate(node:internal/timers:478)
This is almost certainly because Long is emulated on JS, but still this is extremely unintuitive.
c
For BigInt division, the result is the quotient of the two operands truncated towards zero, and the remainder is discarded. A
RangeError
is thrown if the divisor
y
is
0n
. This is because number division by zero returns
Infinity
or
-Infinity
, but BigInt has no concept of infinity.
I guess Koltins
Long
is mapped to
BigInt
k
It's not
It's emulated with two
Int
Looks like the issue on JS is here for Long. This shouldn't throw
Exception
, but instead
ArithmeticExcepion
.
k