Two advantages:
In Golang you can restrict the types usable for a generic with type contraints too.
Returning early in a function for specific conditions is preferred over adding the condition to an if statement because it quickly moves that use case out of the way, so we have more room to focus on the rest of the use cases.
Bubble errors up to the top of the program (handlers or main) to ensure enough context is gathered as much as possible. An expectation to this rule is if the error is expected and is used in a particular case like redis.Nil could signify that a redis key has expired and needs to be recreated.
Return the full error context to the caller (handler) and log the context. If non-handler origin then log the context in the main function.
Errors are good candidates for comparison flags. Wrap errors with %w to compare them if needed during error handling. For example, errors.Is(err, redis.Nil) means err can be wrapped in context but still be compared should a decision be made based on which error occurred.
Always terminate your program as soon as possible when an error occurs that makes running the program any further a fruitless venture. If you don't do this then the program logs are going to make very little sense and you will dig for a very long time to figure out the difference between real error messages and just symptoms of the original error.