How can I implement an ErrorBoundary? I cannot fin...
# javascript
i
How can I implement an ErrorBoundary? I cannot find any code example or explanation on ErrorBoundaries for react. What i did find however, is this ominous class
RComponentClassStatics
and
RStatics
and some 'documentation' here: https://github.com/JetBrains/kotlin-wrappers/blob/master/kotlin-react/src/main/kotlin/react/React.kt#L63-L77 So i tried implementing it like this:
Copy code
external interface ErrorBoundaryState : RState {
    var error: Throwable?
}

class ErrorBoundary : RComponent<RProps, ErrorBoundaryState>() {
    init {
        state.error = null;
    }

    override fun componentDidCatch(error: Throwable, info: RErrorInfo) {
        //super.componentDidCatch(error, info)
        //state.error = error
        //state.errinfo = info
        console.log("ErrorBoundary encountered error:", error)
    }

    override fun RBuilder.render() {
        state.error?.let { e ->
            styledDiv {
                h3 {
                    +"Something went wrong"
                }
                p {
                    +e.toString()
                }
            }
        } ?: props.children()
    }

    companion object : RStatics<RProps, ErrorBoundaryState, ErrorBoundary, Nothing>(ErrorBoundary::class) {
        override var getDerivedStateFromError: ((Throwable) -> ErrorBoundaryState?)?
            get() = {
                object : ErrorBoundaryState {
                    override var error: Throwable?
                        get() = it
                        set(value) {}
                }
            }
            set(value) {
            }
    }
}
However, this fails and nothing is rendered, and I get this error: Warning: ErrorBoundary: Error boundaries should implement getDerivedStateFromError(). In that method, return a state update to display an error message or fallback UI. in ErrorBoundary in Unknown so how is this done properly?
Now, reading the Readme.md of kotlin-react https://github.com/JetBrains/kotlin-wrappers/blob/master/kotlin-react/README.md (which i apparently missed before) i got this instead:
Copy code
companion object : RStatics<RProps, ErrorBoundaryState, ErrorBoundary, Nothing>(ErrorBoundary::class) {
    init {
        getDerivedStateFromError = {
            object : ErrorBoundaryState {
                override var error: Throwable? = it
            }
        }
    }
}
But is still does not work.
t
Copy code
getDerivedStateFromProps = { p, s -> s }
i
it still doesn't work - this is what i get
Copy code
companion object : RStatics<RProps, ErrorBoundaryState, ErrorBoundary, Nothing>(ErrorBoundary::class) {
    init {
        getDerivedStateFromError = {
            object : ErrorBoundaryState {
                override var error: Throwable? = it
            }
        }
        getDerivedStateFromProps = { p, s -> s }
    }
}
this is what the code looks like now
t
No videos 🙂
Props not initialized?
i
The no videos thing is an actual error, but well, that's another unrelated problem ^^ ... i mean that error supposed to be caught by the error boundary, right ;)
t
Copy code
getDerivedStateFromError = { t -> js<ErrorBoundaryState>{
throwable = t   
 } }
fromProps
can be removed
i
hm....that doesnt seem to compile
t
Copy code
getDerivedStateFromError = { t -> jsObject<ErrorBoundaryState>{
throwable = t   
 } }
Works?
i
thanks - this compiles, and looks nicer, than what i had before. However, the error remains the same...
ill opost the code where i use it i guess..
ive minimized is, so all i do in my root App render is this:
Copy code
errorBoundary {
        p {
            +"Test"
            throw RuntimeException("whatever")
        }
    }
using that shortcut:
Copy code
fun RBuilder.errorBoundary(handler: RBuilder.() -> Unit): ReactElement = child(ErrorBoundary::class, handler)
again, ErrorBoundary code hasen't changed except for your suggestions in the companion:
Copy code
external interface ErrorBoundaryState : RState {
    var error: Throwable?
}

class ErrorBoundary : RComponent<RProps, ErrorBoundaryState>() {
    override fun componentDidCatch(error: Throwable, info: RErrorInfo) {
        console.log("ErrorBoundary encountered error:", error)
    }

    override fun RBuilder.render() {
        val error = state.error
        if (error != null) {
            styledDiv {
                h3 {
                    +"Something went wrong"
                }
                p {
                    +error.toString()
                }
            }
        } else props.children()
    }

    companion object : RStatics<RProps, ErrorBoundaryState, ErrorBoundary, Nothing>(ErrorBoundary::class) {
        init {
            getDerivedStateFromError = {
                jsObject<ErrorBoundaryState> {
                    error = it
                }
            }
        }
    }
}
t
GitHub?
i
should i make a gist?
t
Or this
t
line 19 executed?
Copy code
} else props.children()
i
nope, it doesn't seem like it
I updated it to test:
Copy code
override fun RBuilder.render() {
    val error = state.error
    if (error != null) {
        styledDiv {
            h3 {
                +"Something went wrong"
            }
            p {
                +error.toString()
            }
        }
    } else {
        console.log("renderind children")
        props.children()
    }
}
got no "renderind children" log statement printed.
t
companion init called?
i
Oh ... i'm stupid - if i lift the errorboundary up, so its around the App class, it works....
t
🙂
🎉 1
i
the problem apparently was, that the error is caused within the App component itsself so it wasn't caught
thanks for all the help! you'Re awesome!
t
Props, States - JS objects
Use
jsObject
builder for it
👍 1
No
object :
required