The state machine example is a good one. It's a textbook case of unreachable code.
The null-checking example is not good. If the external API returns a null where you don't expect one, UnreachableException will be thrown. It doesn't matter if the documentation says it will never be null; clearly the code isn't unreachable. All you need to reach it is bad data! (InvalidDataException would be a better choice, though arguably not an ideal one.)
If you can write a unit test that makes your code throw UnreachableException, you almost certainly should be throwing a different exception.
This was my initial thought as well, but from the text I gather there is a flow like this:
[Input Data, maybe null] -> Validate field is not null -> Call this method with the assertion.
This is a small bug-bear for me with nullable types and I wish there was a better way to do it, but many languages allow you to smart-cast away nulls, but only within the local scope. If you want to pass a struct-type around which has nullable fields, but you have already checked for non-null (like this one) you need to convert to a different struct-type, which doesn't have the nullability on its fields. I can't think of a good way round this - as you say with the unit test remark, there is nothing to stop another piece of code calling this method with nulls.
If you want to pass a struct-type around which has nullable fields, but you have already checked for non-null (like this one) you need to convert to a different struct-type, which doesn't have the nullability on its fields.
Which is exactly what IMO the author should have done. It's actually a reasonable use-case for inheritance:
I would guess they were spell-checker-corrected, and meant "data" both times: the sentence makes sense with either, though "data" is obviously what makes it make sense in this context :)
Comments
The state machine example is a good one. It's a textbook case of unreachable code.
The null-checking example is not good. If the external API returns a null where you don't expect one, UnreachableException will be thrown. It doesn't matter if the documentation says it will never be null; clearly the code isn't unreachable. All you need to reach it is bad data! (InvalidDataException would be a better choice, though arguably not an ideal one.)
If you can write a unit test that makes your code throw UnreachableException, you almost certainly should be throwing a different exception.
This was my initial thought as well, but from the text I gather there is a flow like this:
[Input Data, maybe null] -> Validate field is not null -> Call this method with the assertion.
This is a small bug-bear for me with nullable types and I wish there was a better way to do it, but many languages allow you to smart-cast away nulls, but only within the local scope. If you want to pass a struct-type around which has nullable fields, but you have already checked for non-null (like this one) you need to convert to a different struct-type, which doesn't have the nullability on its fields. I can't think of a good way round this - as you say with the unit test remark, there is nothing to stop another piece of code calling this method with nulls.
Which is exactly what IMO the author should have done. It's actually a reasonable use-case for inheritance:
ArgumentNullException, InvalidOperationException... There's plenty that have been around since the beginning.
What's more important, that I didn't see in the first two examples, are useful error messages.
`ArgumentNullException` was my first idea too. I would and did use it for this kind of purpose.
Invalid date means you got a value that’s not a valid date which is different than falling into an impossible state.
Invalid Data, not date
I would guess they were spell-checker-corrected, and meant "data" both times: the sentence makes sense with either, though "data" is obviously what makes it make sense in this context :)