How to catch non kotlin exception?


#1

kotlin generates type check in js catch block and rethrows if it fails. Is it possible to write non Throwable catch in kotlin without js("")?


#2

Kotlin Throwable is mapped to js Error. Or do you mean that non-Kotlin exception is not an Error?


#3

After some experimentation I discovered it is possible to do this

fun catchMe() {
    try {
        js("throw 'Some text'")
    } catch(e: dynamic) {
        println("Catched")
    }
}

Which generates js code I was searching for. Is it supported or I found a bug?

btw. What about C++/ SEH on native platforms. From my memories it is possible to throw anything. native will have dynamyc/**Any for integration?


#4

Cathing dynamic exception is a feature that was made intentionally. It’s desgined specially for catching exceptions that are not inherited from JavaScript Error.


#5

How would this be done in the common part of a multiplatform project? I want to catch errors from any platform. I get an error on catch (e: Any). Suggestions? Do I really have to make a expect fun doTry and implement it everywhere to wrap possible JS exceptions into Java errors?


#6

Why would you want to catch all in common code?
What will you do with thrown String in common code? Suppress?

Exceptions are platform dependent anyway. It is possible to throw NaN in js.


#7

I am writing something that does multi-platform conformance checks and it needs to continue regardless of what the underlying code does. The main is in common. Look at this code. Notice how I have Platform.doTry there.

Exactly, so why in the common part of a multiplatform project does it require only the JVM form?


#8

Are you trying to catch expected unusual thrown thingy to pass multiplatform conformance test?

try{code()}catch(Anything){assert("Test passed")}
looks like bad testing method


#9

This is how the protobuf conformance suite works. I can’t just handwave it away as bad practice. This should not be a discussion about practices, but rather a discussion about the fact that you have to drop into platform-specific code to do something as simple as catch-all (whether or not a catch-all is considered good practice).


#10

It throws Strings in Java?


#11

No, it catches all errors. What do you mean by throwing strings? Even the JS doesn’t do that…not sure where strings came from. If I want a multiplatform entry point, I need a multiplatform catch all in this case. Java is just one of the platforms this entry point serves, JS and native are two others. Even if Java wasn’t one of my platforms, I still am restricted to its limitations. I fear I am not making my point clear…ignore Java and pretend it isn’t even one of the platforms I am targeting.


#12

Sure it does https://jsfiddle.net/ncbjhg7t/3/

As for kotlin you can try catching Throwable it is bit magic at least in kotlinjs compiler and should work for typical Error cases.

Here is test that will print message even though java Throwable is not related to js Error

try {
    js("throw Error('Message from JS error')")
} catch (t: Throwable) {
    println(t.message)
}

I have no idea how kotlin native works in this regards


#13

Sorry for the confusion, I was talking about my JS, not JS the language. Clearly JS can throw basically anything.

What if it’s not a js Error instance, does it wrap it to a throwable?


#14

No, see Alexey.Andreev response to my experiment results.


#15

Right, so we’ve come full circle. Simply asked, how do you write a catch-all in multiplatform code? As in, how do you catch anything thrown in multiplatform code. Is it currently unsupported, never going to be supported, etc. I am just wanting a clear answer on this clear question. I can create a YouTrack issue if it should be discussed there.

Right now, for any others, I have to do platform-specific code as a workaround. I have an expect function like:

inline fun <T> doTry(fn: () -> T, errFn: (Any) -> T): T

An actual JVM function like:

actual inline fun <T> doTry(fn: () -> T, errFn: (Any) -> T) = try { fn() } catch (e: Throwable) { errFn(e) }

and an actual JS function like:

actual inline fun <T> doTry(fn: () -> T, errFn: (Any) -> T) =
    try { fn() }
    catch (e: Throwable) {  errFn(e) }
    catch (e: dynamic) { errFn(e as Any) }