assert() vs throw

Assertions should only be used to verify conditions that should be logically impossible to be false. These conditions should only be based on inputs generated by your own code. Any checks based on external inputs should use exceptions.

The best use case of assert() is to treat it as a docblock to specify types (great to nullables and polymorphic types). assert() may be disabled on production, so please do not rely on it in a runtime, prefer Exceptions instead if you need to check an expression in a runtime.

Make sure you add a description to assert so that it's easy to reason about the code when a failure occurs.

From official documentation:

Assertions should be used as a debugging feature only. You may use them for sanity-checks that test for conditions that should always be true and that indicate some programming errors if not or to check for the presence of certain features like extension functions or certain system limits and features.