Failure isolation
What happens when your menu code throws - which failures turn only your menu off, which are just logged, and how mistakes in builders show up.
On this page
Any number of mods can register menus, and one mod's bug never breaks another's, or the game. What happens depends on where your code throws.
The three outcomes#
| Your code throws in… | Result |
|---|---|
ScreenFactory.create or buttonLabel, or any supplier (label, value, enabled, visible, tooltip, rows, validator), or create returns null |
Your menu turns off for the rest of the session. The error is logged once, naming your mod. Other mods' menus keep working. |
an action: onPress, onChange, onSelect, onToggle, a dialog answer, a runOnMainThread task, a runAsync callback |
The error is logged with your mod id, and the menu stays open. |
a builder's build() (a missing required field, a bad id, a bad range) |
It throws at once, with a message naming the widget and the field, so it shows up in development. |
A runAsync task that throws is none of these: its exception goes to your onDone as the second argument.
What players see when your menu is off#
- Opening your menu shows a screen saying: "This menu stopped after an error and is off until the game restarts. The game log has the details."
- In the "Mod menus" list, your button is greyed out with that text as its tooltip.
MultiversionUi.menuScreen("mymod", parent)returns that same screen.
The log line looks like this, followed by the stack trace:
[Xi's Multiversion UI Lib] ERROR Building the first screen of mymod's menu failed in mod mymod's menu code: its menu is off until the game restarts. Other mods' menus still work.
Your exceptions stay yours#
The library doesn't wrap your exceptions. Your own catch blocks receive them unchanged; the library only adds
a suppressed entry to the stack trace that names your mod, which is how it knows whose menu to turn off.
When the library itself fails#
If one of the library's own hooks throws, for example because a Minecraft update renamed something, every mod's menu turns off for the session and the error is logged once. The game and every mod keep running; they just have no menus. Screens that are already open stay usable, so the player can leave them.
Write code that doesn't turn off#
- Keep suppliers trivial: read a field, format a string. Do the risky part in an action or in
runAsync, where a failure is only logged. - Catch expected errors in actions and show them in a StatusLine instead of letting them reach the log.
- Check
Failsafe.enabled("mymod")if you need to know whether your menu is still on, andFailsafe.enabled()for the library as a whole. See Failsafe.
Testing the failure path#
| JVM flag | Effect |
|---|---|
-Dxis_mvui.forceError=true |
every library hook fails, to test that the game survives with menus off |
-Dxis_mvui.disable=true |
turns the library off: no backend, no menus |
In unit tests with FakeHost, an unregistered menu isn't guarded at all, so your exception reaches the test
directly.
Next steps#
- Threads: where each kind of code runs.
- The wiki's troubleshooting page, for what players can do.