Skip to content

Safeguard block breaking and item damage against collectible behavior exceptions (#282) - #336

Open
Zaldaryon wants to merge 1 commit into
indevfrom
fix/issue-282-item-break-exception
Open

Zaldaryon wants to merge 1 commit into
indevfrom
fix/issue-282-item-break-exception

Conversation

@Zaldaryon

Copy link
Copy Markdown
Contributor

Summary

Safeguard block breaking and tool damage against unhandled exceptions thrown by collectible behaviors, resolving #282.

When an external mod behavior throws an unhandled exception during item damage (such as Toolsmith's NullReferenceException in TinkeringUtility.HandleBrokenTinkeredTool when an untracked tinkered tool breaks), the exception escaped ServerSystemBlockSimulation.TryModifyBlockInWorld directly into ServerMain.DispatchClientPacket_mainthread. On dedicated servers, any unhandled exception in client packet dispatch forcibly kicks the player with "Threw an exception at the server" ("An action you or your client did caused an unhandled exception"), aborting block removal and leaving player inventory dirty states out of sync.

This change introduces defensive handling across the breaking pipeline:

  1. Collectible.WalkBehaviors wraps behavior invocations in try-catch blocks. If a mod's OnDamageItem throws, the exception is logged to the server logger while allowing vanilla default actions (item damage reduction and slot clearing on zero durability) to complete cleanly.
  2. Collectible.OnBlockBrokenWith wraps behavior callbacks in try-catch blocks so third-party mod failures log rather than crashing the breaking sequence.
  3. ServerSystemBlockSimulation.TryModifyBlockInWorld wraps OnBlockBrokenWith and block4.OnBlockBroken in a try-catch block. If an exception occurs and the target block was not yet removed, a fallback block break runs so the block is not left in an inconsistent state, and the player is not disconnected.
  4. Added Atlas regression scenarios in ItemBreakResilienceScenarios.cs reproducing both failure modes under dedicated server conditions (IsDedicatedServer == true).

Type

  • Bug fix
  • Performance
  • New feature
  • Refactor or cleanup
  • Docs or build

Checklist

  • .\scripts\extract-patches.ps1 ran clean.
  • dotnet build VintageStory.slnx -c Release -p:EmbedPatchedFiles=true is green.
  • Every vanilla edit has a // Stratum marker.
  • No vanilla source committed.
  • Tested on a real server start, not just compilation.

Related issues

Fixes #282

… exceptions

When an external mod behavior throws an unhandled exception during item
damage (such as Toolsmith's NRE when an untracked tinkered tool breaks),
the exception previously escaped ServerSystemBlockSimulation into
DispatchClientPacket_mainthread, causing the dedicated server to
forcibly kick the player with an unhandled exception notice while leaving
block and inventory state unfinalized.

Wrap Collectible.WalkBehaviors and Collectible.OnBlockBrokenWith in
try-catch blocks so faulty mod behaviors log their error to the server
logger while allowing vanilla default actions (item damage and break
handling) to proceed. In addition, wrap TryModifyBlockInWorld item and
block break callbacks with a fallback block removal if unhandled exceptions
occur, ensuring dedicated servers do not disconnect players when third-party
mod item breaking logic fails. Add regression Atlas scenarios covering both
failure modes.

Fixes #282
@Zaldaryon
Zaldaryon marked this pull request as ready for review September 17, 2026 00:33
@Zaldaryon
Zaldaryon removed the request for review from pizza2004 September 17, 2026 00:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant