The main problem is understanding when to throw errors. And remember, the mission for the corresponding try..catch with objects is two step: first to deconstruct and then to handle errors in the most specific way possible, certainly not in a general manner.
Doing it the clean way, like I did, keeping constraints outside the constructor, assures error handling on spot, before the fact, before entering or calling the constructor, before any work is done: if criteria is met then enter the constructor.
Doing it like the OP did, putting the constrains inside the constructor results in a messy way of error handling, after some work has already been done: first entering or calling the constructor, then checking if criteria is met: throwing the error and then handling the error. The first two steps are memory consuming for nothing (why would you want to load the constructor before checking if you meet the criteria) and the last step is bound to make you forget to catch one thing or another.