Breakdown of possible fixes to avoid future erroneous state and runtime panic #26

Closed
opened 2025-09-05 17:19:38 +02:00 by Opoodoop · 1 comment
Contributor

The panic mentioned in #8 was caused by an index into an array being out of bounds and could be avoided by checking the value and skipping writing if the index is invalid. Below is a breakdown of a subset of the most common causes of panics to be evaluated on which can be handled gracefully and which are irrecoverable. Handling all of these cases are not likely to be possible as some irrecoverable states are expected in many projects but determining which are and avoiding code like it in the future will help the project avoid a large amount of bugs as it grows more mature.

Cheers! :)

Total instances of call to unwrap() not including unwrap_or() unwrap_or_default() or similar. The bare unwrap() function panics if called on anything other than an Ok() type
Regex used: unwrap()
total: 751

File Instances
data\src\blocks.rs 271
data\src\items.rs 1
data_generator_tools\src\main.rs 48
lib\src\deserialize.rs 50
lib\src\serialize.rs 6
lib\src\utils.rs 4
lib\src\blockstates\mod.rs 9
lib\src\packets\clientbound\configuration.rs 3
lib\src\packets\clientbound\play.rs 15
lib\src\types\command.rs 14
lib\src\types\world\mod.rs 2
lib\src\types\world\loader\vanilla.rs 75
proxy\src\main.rs 91
server\src\main.rs 29
server\src\packet_handlers.rs 60
server\src\terminal_input.rs 6
server\src\panic.rs 6
server\src\command\print_players.rs 1
server\src\command\saveall.rs 1
server\src\command\tell.rs 4
server\src\command\tp.rs 6
server\src\types\player.rs 54

Total instances of reading from or writing to an array (attempted to avoid matching type declaration). Writing to or reading from a vector out of range by accident is quite common and will lead to a panic at runtime.
Regex used: (?<!#!)(?<!#)(?<! )(?<!&)(?<!\[)(?<!vec!)\[
Total: 133

File Instances
data_generator_tools/src/main.rs 32
lib/src/deserialize.rs 1
lib/src/serialize.rs 1
lib/src/utils.rs 7
lib/src/types/world/mod.rs 4
lib/src/types/world/loader/vanilla.rs 42
server/src/packet_handler.rs 16
server/src/command/mod.rs 2
server/src/types/player.rs 28

Total instances of division, the denominator (divisor) must never be zero, division by zero results in a panic at runtime.
Regex used: ( / )|( % )
Total: 52

File Instances
lib/src/packets/clientbound/play.rs 12
lib/src/types/position.rs 10
lib/src/types/world/mod.rs 2
lib/src/types/world/loader/vanilla.rs 8
server/src/packet_handlers.rs 18
server/src/types/player.rs 2

Sorry for the long issue. I tried to make it concise but still detailed.

The panic mentioned in #8 was caused by an index into an array being out of bounds and could be avoided by checking the value and skipping writing if the index is invalid. Below is a breakdown of a subset of the most common causes of panics to be evaluated on which can be handled gracefully and which are irrecoverable. Handling all of these cases are not likely to be possible as some irrecoverable states are expected in many projects but determining which are and avoiding code like it in the future will help the project avoid a large amount of bugs as it grows more mature. Cheers! :) Total instances of call to unwrap() not including unwrap_or() unwrap_or_default() or similar. The bare unwrap() function panics if called on anything other than an Ok() type Regex used: `unwrap()` `total: 751` | File | Instances | |---------|---------| | data\src\blocks.rs | 271 | | data\src\items.rs | 1 | | data_generator_tools\src\main.rs | 48 | | lib\src\deserialize.rs | 50 | | lib\src\serialize.rs | 6 | | lib\src\utils.rs | 4 | | lib\src\blockstates\mod.rs | 9 | | lib\src\packets\clientbound\configuration.rs | 3 | | lib\src\packets\clientbound\play.rs | 15 | | lib\src\types\command.rs | 14 | | lib\src\types\world\mod.rs | 2 | | lib\src\types\world\loader\vanilla.rs | 75 | | proxy\src\main.rs | 91 | | server\src\main.rs | 29 | | server\src\packet_handlers.rs | 60 | | server\src\terminal_input.rs | 6 | | server\src\panic.rs | 6 | | server\src\command\print_players.rs | 1 | | server\src\command\saveall.rs | 1 | | server\src\command\tell.rs | 4 | | server\src\command\tp.rs | 6 | | server\src\types\player.rs | 54 | Total instances of reading from or writing to an array (attempted to avoid matching type declaration). Writing to or reading from a vector out of range by accident is quite common and will lead to a panic at runtime. Regex used: `(?<!#!)(?<!#)(?<! )(?<!&)(?<!\[)(?<!vec!)\[` `Total: 133` | File | Instances | |---------|---------| | data_generator_tools/src/main.rs | 32 | | lib/src/deserialize.rs | 1 | | lib/src/serialize.rs | 1 | | lib/src/utils.rs | 7 | | lib/src/types/world/mod.rs | 4 | | lib/src/types/world/loader/vanilla.rs | 42 | | server/src/packet_handler.rs | 16 | | server/src/command/mod.rs | 2 | | server/src/types/player.rs | 28 | Total instances of division, the denominator (divisor) must never be zero, division by zero results in a panic at runtime. Regex used: `( / )|( % )` `Total: 52` | File | Instances | |---------|---------| | lib/src/packets/clientbound/play.rs | 12 | | lib/src/types/position.rs | 10 | | lib/src/types/world/mod.rs | 2 | | lib/src/types/world/loader/vanilla.rs | 8 | | server/src/packet_handlers.rs | 18 | | server/src/types/player.rs | 2 | Sorry for the long issue. I tried to make it concise but still detailed.
Owner

The array mentioned in #8 stores the block state IDs of a single chunk section, so its length will always be 4096. The only case where this is different, is when a chunk section only contains air, then the array is simply empty. I just forgot to check if a section is empty before placing a new block within it.
And yes I am aware that unwrap() will panic. I will gradually add more robust error handling logic as things get more mature (:

The array mentioned in #8 stores the block state IDs of a single chunk section, so its length will _always_ be 4096. The only case where this is different, is when a chunk section only contains air, then the array is simply empty. I just forgot to check if a section is empty before placing a new block within it. And yes I am aware that unwrap() will panic. I will gradually add more robust error handling logic as things get more mature (:
Sign in to join this conversation.
No description provided.