Always use semantically correct error types and codes that match the actual failure scenario. This ensures proper error handling by callers and consistent API behavior across the system.

Key Guidelines:

Examples:

Incorrect - Wrong error type for not found:

return nil, s.sqlstore.WrapNotFoundErrf(err, errors.CodeInternal, "unable to fetch the license with ID: %s", licenseID)

Correct - Proper not found error:

return nil, s.sqlstore.WrapNotFoundErrf(err, errors.CodeNotFound, "unable to fetch the license with ID: %s", licenseID)

Incorrect - Wrong error type for validation:

return errors.Wrapf(nil, errors.TypeForbidden, errors.CodeForbidden, "s3 buckets can only be added to service-type[%s]", services.S3Sync)

Correct - Proper validation error:

return errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "s3 buckets can only be added to service-type[%s]", services.S3Sync)

Incorrect - Missing error check:

tracesJSON, _ := json.Marshal(tracesFilters)

Correct - Always check errors:

tracesJSON, err := json.Marshal(tracesFilters)
if err != nil {
    return nil, err
}

This practice ensures that error handling is predictable and allows callers to make appropriate decisions based on the specific type of failure.