sometimes impossible to recover on infinite loop crash
this could be mitigated with a run button along with an option to not automatically run on code changes (similar to codepen).
As a temporary workaround, I close the tab, re-open it then quickly copy the whole text, close it, open a fresh empty playground, paste the modified text with the following added to the top to prevent it from looping:
thro();
function thro() {
throw "";
}
The thro() function is needed so that a plain throw statement doesn't break type checking, because TS thinks the lines after it are unreachable.
Interesting! I've thought about adding a "run" button but need to think a little bit more how to display that in the UI. Probably would take the form of a checkbox to toggle auto refresh and a button that would appear when that option would be checked.
As per the infinite loop issue, I'd like for the playground to automatically figure things out. Codesandbox has an option for that as well.

I wonder if looking for every JS loop and adding a counter in it which would throw if the increment is over 10k or something would be sufficient...
Solid does have some infinite loop protection. But it only works in tight loops. I imagine if you are hitting one here it is a larger one. This makes me think it is unlikely a simple loop counter will work.
Oh thanks Ryan for the quick heads-up, I had no idea Solid had some of this built-in! Yeah I see, I need to dig this a little bit more. It's very possible the run button in itself would be more than enough.
this makes the solidjs playground hang forever
bad
import { render, For } from "solid-js/web";
import { createSignal, children } from "solid-js";
import { createStore } from "solid-js/store";
function Button(props) {
const getChildren = children(() => props.children);
const getOnClick = children(() => props.onClick); // FIXME
return (
<button type="button" onClick={(() => props.onClick)()}>
<For each={getChildren()}>{item => <div>{item}</div>}</For>
</button>
);
}
function App() {
const [store, setStore] = createStore({ count: 0 });
const increment = () => {
setStore('count', store.count + 1);
console.log(`store.count=${store.count}`);
};
return (
<Button onClick={increment}>
{store.count}
</Button>
);
}
render(() => <App />, document.getElementById("app")!);
good
import { render, For } from "solid-js/web";
import { createSignal, children } from "solid-js";
import { createStore } from "solid-js/store";
function Button(props) {
const getChildren = children(() => props.children);
const getOnClick = () => props.onClick;
return (
<button type="button" onClick={getOnClick()}>
{getChildren()}
</button>
);
}
function App() {
const [store, setStore] = createStore({ count: 0 });
const increment = () => {
setStore('count', store.count + 1);
console.log(`store.count=${store.count}`);
};
return (
<Button onClick={increment}>
{store.count}
</Button>
);
}
render(() => <App />, document.getElementById("app")!);
diff
function Button(props) {
const getChildren = children(() => props.children);
- const getOnClick = children(() => props.onClick); // FIXME
+ const getOnClick = () => props.onClick;
return (
- <button type="button" onClick={(() => props.onClick)()}>
- <For each={getChildren()}>{item => <div>{item}</div>}</For>
+ <button type="button" onClick={getOnClick()}>
+ {getChildren()}
</button>
);
}
You can delete the cache of the crashing code from browser localStorage for the solidjs playground site
Oh yeah, right! Now that the playground remembers your previous code, refreshing always gets back to crashing state. :D