Crafting Custom Errors in Go
In Go, errors are a fundamental part of handling unexpected situations. While Go provides built-in error types, creating custom error types allows for more structured and informative error handling. This challenge will guide you in defining and using your own custom error types to represent specific failure scenarios in a program.
Problem Description
Your task is to implement a simple user registration system that validates user input. You need to define custom error types to clearly indicate different validation failures. Specifically, you will create two custom error types:
InvalidEmailError: To be returned when an email address is not in a valid format.PasswordTooShortError: To be returned when a password is shorter than the minimum required length.
You will then implement a RegisterUser function that takes a username, email, and password. This function should perform the following validations:
- The email must contain an "@" symbol.
- The password must be at least 8 characters long.
If any validation fails, the function should return the appropriate custom error. If all validations pass, it should return nil for the error.
Key Requirements
- Define a custom error type
InvalidEmailErrorthat implements theerrorinterface. - Define a custom error type
PasswordTooShortErrorthat implements theerrorinterface. - Implement the
RegisterUserfunction which takesusername,email, andpassword(all strings). - The
RegisterUserfunction should return anerror. - Inside
RegisterUser, check for email validity (presence of "@"). If invalid, returnInvalidEmailError. - Inside
RegisterUser, check for password length (minimum 8 characters). If too short, returnPasswordTooShortError. - If both validations pass,
RegisterUsershould returnnil.
Expected Behavior
When RegisterUser is called with invalid input, it should return the corresponding custom error. When called with valid input, it should return nil. The caller of RegisterUser should be able to distinguish between the different custom errors using type assertions.
Important Edge Cases
- Empty strings for email and password.
- Emails with multiple "@" symbols (though for this challenge, just the presence of one is sufficient).
Examples
Example 1:
Input:
username: "john_doe"
email: "john.doe@example.com"
password: "securepassword123"
Output:
nil
Explanation: The email is valid (contains "@") and the password is long enough (17 characters > 8).
Example 2:
Input:
username: "jane_doe"
email: "janedoeexample.com"
password: "short"
Output:
InvalidEmailError
Explanation: The email "janedoeexample.com" is missing the "@" symbol, triggering an `InvalidEmailError`.
Example 3:
Input:
username: "peter_pan"
email: "peter@neverland.com"
password: "weak"
Output:
PasswordTooShortError
Explanation: The email "peter@neverland.com" is valid, but the password "weak" is only 4 characters long, which is less than the required 8, triggering a `PasswordTooShortError`.
Example 4:
Input:
username: "alice"
email: ""
password: ""
Output:
InvalidEmailError
Explanation: An empty email string does not contain "@", triggering an `InvalidEmailError`. The password is also too short, but the email validation fails first.
Constraints
- Input strings for username, email, and password will not be
nil. - The minimum password length is strictly 8 characters.
- The focus of this challenge is on error definition and handling, not on complex email or password pattern matching.
Notes
- Remember to define your custom error types as structs.
- Implement the
Error()method for each custom error type to satisfy theerrorinterface. This method should return a descriptive string. - When handling errors returned by
RegisterUser, you can use type assertions (e.g.,if err, ok := err.(InvalidEmailError); ok { ... }) to check for specific custom error types. - Consider how your custom error messages can provide useful context to the user or developer.