Decoupling our validation logic

However, we cannot directly copy our existing validation code from src/handlers/users/create.js without modification. This is because the validation code directly modifies the response object, res, which means that the validation logic and response logic are tightly coupled to each other.

To resolve this, we must define a common interface between our validation logic and our response handler. Instead of modifying the response directly, the validation logic will produce an object that conforms to this interface, and the response handler will consume this object to produce an appropriate response.

When a request fails validation, we can consider it as a type of error, because the client provided an incorrect payload. Therefore, we can extend the native Error object to create a new ValidationError object, which will act as the interface. We don't have to provide the status or set the headers, as that's the job of our request handlers. We just need to make sure an instance of ValidationError will contain the message property. Since this is the default behavior of Error, we don't need to do much else.