-
Hi everyone! I am not quite sure if i understand how the Example here: Do i need to handle this kind of errors on my own? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
Yeah, inside a click handler is outside of the rendering flow. ErrorBoundaries handle issues with rendering, or reactive propagation, or view code. Throwing an error in an event handler there is no hierarchy there anymore as it is just attached to the DOM. There might be some ways to push that context in, but it isn't there by default right now. |
Beta Was this translation helpful? Give feedback.
-
I also had the problem of wanting an Error Boundary to handle an error outside the rendering flow, so the user knows something went wrong and the app doesn't continue with a corrupted state. I managed to solve it by creating a custom hook Here are the relevant parts of my code as an example, maybe it helps someone with the same problem: function useAuthStateChangeListener(listenerFunc: AuthStateChangeListener) {
const throwErrorsToErrorBoundary = useThrowErrorsToErrorBoundary();
onMount(() => {
FirebaseAuthentication.addListener("authStateChange", change => {
throwErrorsToErrorBoundary(() => {
listenerFunc(change); // this may throw, but it's outside render
});
});
});
}
function useThrowErrorsToErrorBoundary(): (fnThatMayThrow: () => void) => void {
const owner = getOwner();
return function throwErrorsToErrorBoundary(fnThatMayThrow: () => void): void {
runWithOwner(owner, fnThatMayThrow);
};
} |
Beta Was this translation helpful? Give feedback.
-
Hi all, This was a bit counter-intuitive at first, but makes sense now that I wrapped my head around it. The error needs to be re-thrown within the right scope inside the onMount(() => {
const owner = getOwner();
api
.connect()
.catch((err) => runWithOwner(owner, () => { throw err })
}); This can be abstracted multiple ways, but by dedicating a component to do the tracking, it can be applied in the same component that defines the Usage <ErrorBoundary fallback={({ message }) => <div>Error: {message}</div>}>
<Track func={() => api.connect()} />
<Show when={connected()} fallback={<Loading />}>
<PageListings />
</Show>
</ErrorBoundary>
import { Component, getOwner } from "solid-js";
import { throwToOwner } from "~/lib/utils";
/**
* Component that tracks scope and runs a function
* @param props.func Function to run in scope
* @returns
*/
export const Track: Component<{
func: Function;
}> = (props) => {
const owner = getOwner();
props.func().catch(throwToOwner(owner!));
return null;
}; And finally the util-function /**
* Rethrows an error inside a SolidJs tracked scope.
* @param ownerScope SolidJs owner-scope from `getOwner()`
* @returns undefined
*/
export const throwToOwner = (ownerScope: Owner): any => (err: any) => {
console.warn('throwToOwner:', err)
runWithOwner(ownerScope!, () => {
throw err;
});
} Any better ways of doing this, I'm all ears! Cheers! |
Beta Was this translation helpful? Give feedback.
Yeah, inside a click handler is outside of the rendering flow. ErrorBoundaries handle issues with rendering, or reactive propagation, or view code. Throwing an error in an event handler there is no hierarchy there anymore as it is just attached to the DOM. There might be some ways to push that context in, but it isn't there by default right now.