Constructors are dedicated language-sanctioned functions that transform (data inputs X) into (type/object Y).
The given X should be subjected to the requirements necessary to create a valid Y. If the requirements fail, you have two main choices: Create an invalid Y, or reject X & return an error in however you want it to be returned.
The former leaks said rejections throughout the rest of the type's/object's code, & makes more work for me to parse through where & how the problem occurs.
The latter option creates a cleaner system altogether, due to rejecting sections of invalid states. Not all will be rejected, but the fact that some do get rejected already makes its workload comparatively lighter than the former.
I know which my lazy bum would pick.