Parcourir la source

refactor(internal): use errors.Is instead of equality operator

errors.Is unwraps nested error. This makes check less error prone.
gudvinr il y a 1 semaine
Parent
commit
3f05747a78

+ 3 - 2
internal/database/migrations.go

@@ -5,6 +5,7 @@ package database // import "miniflux.app/v2/internal/database"
 
 import (
 	"database/sql"
+	"errors"
 
 	"miniflux.app/v2/internal/crypto"
 )
@@ -483,7 +484,7 @@ var migrations = [...]func(tx *sql.Tx) error{
 			)
 
 			if err := tx.QueryRow(`FETCH NEXT FROM my_cursor`).Scan(&userID, &customStylesheet, &googleID, &oidcID); err != nil {
-				if err == sql.ErrNoRows {
+				if errors.Is(err, sql.ErrNoRows) {
 					break
 				}
 				return err
@@ -1081,7 +1082,7 @@ var migrations = [...]func(tx *sql.Tx) error{
 			var id int64
 
 			if err := tx.QueryRow(`FETCH NEXT FROM id_cursor`).Scan(&id); err != nil {
-				if err == sql.ErrNoRows {
+				if errors.Is(err, sql.ErrNoRows) {
 					break
 				}
 				return err

+ 13 - 10
internal/reader/fetcher/response_handler.go

@@ -243,30 +243,33 @@ func (r *ResponseHandler) isCloudflareChallenge() bool {
 }
 
 func isNetworkError(err error) bool {
-	if _, ok := err.(*url.Error); ok {
+	if _, ok := errors.AsType[*url.Error](err); ok {
 		return true
 	}
-	if err == io.EOF {
+
+	if errors.Is(err, io.EOF) {
 		return true
 	}
-	var opErr *net.OpError
-	if ok := errors.As(err, &opErr); ok {
+
+	if _, ok := errors.AsType[*net.OpError](err); ok {
 		return true
 	}
+
 	return false
 }
 
 func isSSLError(err error) bool {
-	var certErr x509.UnknownAuthorityError
-	if errors.As(err, &certErr) {
+	if _, ok := errors.AsType[x509.UnknownAuthorityError](err); ok {
 		return true
 	}
 
-	var hostErr x509.HostnameError
-	if errors.As(err, &hostErr) {
+	if _, ok := errors.AsType[x509.HostnameError](err); ok {
 		return true
 	}
 
-	var algErr x509.InsecureAlgorithmError
-	return errors.As(err, &algErr)
+	if _, ok := errors.AsType[x509.InsecureAlgorithmError](err); ok {
+		return true
+	}
+
+	return false
 }

+ 2 - 1
internal/reader/parser/format.go

@@ -5,6 +5,7 @@ package parser // import "miniflux.app/v2/internal/reader/parser"
 
 import (
 	"encoding/xml"
+	"errors"
 	"io"
 	"unicode"
 
@@ -71,7 +72,7 @@ func detectJSONFormat(r io.ReadSeeker) (bool, error) {
 	for {
 		n, err := r.Read(buffer)
 		if n == 0 {
-			if err == io.EOF {
+			if errors.Is(err, io.EOF) {
 				return false, nil // No non-whitespace content found
 			}
 			return false, err

+ 2 - 1
internal/reader/sanitizer/strip_tags.go

@@ -4,6 +4,7 @@
 package sanitizer // import "miniflux.app/v2/internal/reader/sanitizer"
 
 import (
+	"errors"
 	"io"
 	"strings"
 
@@ -19,7 +20,7 @@ func StripTags(input string) string {
 	for {
 		if tokenizer.Next() == html.ErrorToken {
 			err := tokenizer.Err()
-			if err == io.EOF {
+			if errors.Is(err, io.EOF) {
 				return buffer.String()
 			}
 

+ 3 - 3
internal/storage/category.go

@@ -44,7 +44,7 @@ func (s *Storage) Category(userID, categoryID int64) (*model.Category, error) {
 	err := s.db.QueryRow(query, userID, categoryID).Scan(&category.ID, &category.UserID, &category.Title, &category.HideGlobally)
 
 	switch {
-	case err == sql.ErrNoRows:
+	case errors.Is(err, sql.ErrNoRows):
 		return nil, nil
 	case err != nil:
 		return nil, fmt.Errorf(`store: unable to fetch category: %v`, err)
@@ -61,7 +61,7 @@ func (s *Storage) FirstCategory(userID int64) (*model.Category, error) {
 	err := s.db.QueryRow(query, userID).Scan(&category.ID, &category.UserID, &category.Title, &category.HideGlobally)
 
 	switch {
-	case err == sql.ErrNoRows:
+	case errors.Is(err, sql.ErrNoRows):
 		return nil, nil
 	case err != nil:
 		return nil, fmt.Errorf(`store: unable to fetch category: %v`, err)
@@ -78,7 +78,7 @@ func (s *Storage) CategoryByTitle(userID int64, title string) (*model.Category,
 	err := s.db.QueryRow(query, userID, title).Scan(&category.ID, &category.UserID, &category.Title, &category.HideGlobally)
 
 	switch {
-	case err == sql.ErrNoRows:
+	case errors.Is(err, sql.ErrNoRows):
 		return nil, nil
 	case err != nil:
 		return nil, fmt.Errorf(`store: unable to fetch category: %v`, err)

+ 2 - 1
internal/storage/certificate_cache.go

@@ -6,6 +6,7 @@ package storage // import "miniflux.app/v2/internal/storage"
 import (
 	"context"
 	"database/sql"
+	"errors"
 
 	"golang.org/x/crypto/acme/autocert"
 )
@@ -32,7 +33,7 @@ func (c *certificateCache) Get(ctx context.Context, key string) ([]byte, error)
 	query := `SELECT data::bytea FROM acme_cache WHERE key = $1`
 	var data []byte
 	err := c.storage.db.QueryRowContext(ctx, query, key).Scan(&data)
-	if err == sql.ErrNoRows {
+	if errors.Is(err, sql.ErrNoRows) {
 		return nil, autocert.ErrCacheMiss
 	}
 

+ 2 - 1
internal/storage/enclosure.go

@@ -5,6 +5,7 @@ package storage // import "miniflux.app/v2/internal/storage"
 
 import (
 	"database/sql"
+	"errors"
 	"fmt"
 	"strings"
 
@@ -135,7 +136,7 @@ func (s *Storage) GetEnclosure(enclosureID int64) (*model.Enclosure, error) {
 		&enclosure.MediaProgression,
 	)
 
-	if err == sql.ErrNoRows {
+	if errors.Is(err, sql.ErrNoRows) {
 		return nil, nil
 	} else if err != nil {
 		return nil, fmt.Errorf(`store: unable to fetch enclosure row: %v`, err)

+ 1 - 1
internal/storage/entry.go

@@ -237,7 +237,7 @@ func (s *Storage) getEntryIDByHash(tx *sql.Tx, feedID int64, entryHash string) (
 		entryHash,
 	).Scan(&entryID)
 
-	if err == sql.ErrNoRows {
+	if errors.Is(err, sql.ErrNoRows) {
 		return 0, nil
 	}
 	if err != nil {

+ 3 - 2
internal/storage/entry_pagination_builder.go

@@ -5,6 +5,7 @@ package storage // import "miniflux.app/v2/internal/storage"
 
 import (
 	"database/sql"
+	"errors"
 	"fmt"
 	"strconv"
 	"strings"
@@ -149,7 +150,7 @@ func (e *entryPaginationBuilder) getPrevNextID(tx *sql.Tx) (prevID int64, nextID
 	var pID, nID sql.NullInt64
 	err = tx.QueryRow(query, e.args...).Scan(&pID, &nID)
 	switch {
-	case err == sql.ErrNoRows:
+	case errors.Is(err, sql.ErrNoRows):
 		return 0, 0, nil
 	case err != nil:
 		return 0, 0, fmt.Errorf("entry pagination: %v", err)
@@ -175,7 +176,7 @@ func (e *entryPaginationBuilder) getEntry(tx *sql.Tx, entryID int64) (*model.Ent
 	)
 
 	switch {
-	case err == sql.ErrNoRows:
+	case errors.Is(err, sql.ErrNoRows):
 		return nil, nil
 	case err != nil:
 		return nil, fmt.Errorf("fetching sibling entry: %v", err)

+ 6 - 5
internal/storage/icon.go

@@ -5,6 +5,7 @@ package storage // import "miniflux.app/v2/internal/storage"
 
 import (
 	"database/sql"
+	"errors"
 	"fmt"
 	"strings"
 
@@ -34,7 +35,7 @@ func (s *Storage) IconByID(iconID int64) (*model.Icon, error) {
 		WHERE id=$1`
 	err := s.db.QueryRow(query, iconID).Scan(&icon.ID, &icon.Hash, &icon.MimeType, &icon.Content, &icon.ExternalID)
 	switch {
-	case err == sql.ErrNoRows:
+	case errors.Is(err, sql.ErrNoRows):
 		return nil, nil
 	case err != nil:
 		return nil, fmt.Errorf("store: cannot load icon id=%d: %w", iconID, err)
@@ -58,7 +59,7 @@ func (s *Storage) IconByExternalID(externalIconID string) (*model.Icon, error) {
 	`
 	err := s.db.QueryRow(query, externalIconID).Scan(&icon.ID, &icon.Hash, &icon.MimeType, &icon.Content, &icon.ExternalID)
 	switch {
-	case err == sql.ErrNoRows:
+	case errors.Is(err, sql.ErrNoRows):
 		return nil, nil
 	case err != nil:
 		return nil, fmt.Errorf("store: cannot load icon external_id=%s: %w", externalIconID, err)
@@ -86,7 +87,7 @@ func (s *Storage) IconByFeedID(userID, feedID int64) (*model.Icon, error) {
 	var icon model.Icon
 	err := s.db.QueryRow(query, userID, feedID).Scan(&icon.ID, &icon.Hash, &icon.MimeType, &icon.Content, &icon.ExternalID)
 	switch {
-	case err == sql.ErrNoRows:
+	case errors.Is(err, sql.ErrNoRows):
 		return nil, nil
 	case err != nil:
 		return nil, fmt.Errorf("store: cannot load icon for feed_id=%d user_id=%d: %w", feedID, userID, err)
@@ -102,7 +103,8 @@ func (s *Storage) StoreFeedIcon(feedID int64, icon *model.Icon) error {
 		return fmt.Errorf(`store: unable to start transaction: %v`, err)
 	}
 
-	if err := tx.QueryRow(`SELECT id FROM icons WHERE hash=$1`, icon.Hash).Scan(&icon.ID); err == sql.ErrNoRows {
+	err = tx.QueryRow(`SELECT id FROM icons WHERE hash=$1`, icon.Hash).Scan(&icon.ID)
+	if errors.Is(err, sql.ErrNoRows) {
 		query := `
 			INSERT INTO icons
 				(hash, mime_type, content, external_id)
@@ -118,7 +120,6 @@ func (s *Storage) StoreFeedIcon(feedID int64, icon *model.Icon) error {
 			icon.Content,
 			crypto.GenerateRandomStringHex(20),
 		).Scan(&icon.ID)
-
 		if err != nil {
 			tx.Rollback()
 			return fmt.Errorf(`store: unable to create icon: %v`, err)

+ 5 - 4
internal/storage/integration.go

@@ -5,6 +5,7 @@ package storage // import "miniflux.app/v2/internal/storage"
 
 import (
 	"database/sql"
+	"errors"
 	"fmt"
 
 	"golang.org/x/crypto/bcrypt"
@@ -43,7 +44,7 @@ func (s *Storage) UserByFeverToken(token string) (*model.User, error) {
 	var user model.User
 	err := s.db.QueryRow(query, token).Scan(&user.ID, &user.Username, &user.IsAdmin, &user.Timezone)
 	switch {
-	case err == sql.ErrNoRows:
+	case errors.Is(err, sql.ErrNoRows):
 		return nil, nil
 	case err != nil:
 		return nil, fmt.Errorf("store: unable to fetch user: %v", err)
@@ -66,7 +67,7 @@ func (s *Storage) GoogleReaderUserCheckPassword(username, password string) error
 	`
 
 	err := s.db.QueryRow(query, username).Scan(&hash)
-	if err == sql.ErrNoRows {
+	if errors.Is(err, sql.ErrNoRows) {
 		return fmt.Errorf(`store: unable to find this user: %s`, username)
 	} else if err != nil {
 		return fmt.Errorf(`store: unable to fetch user: %v`, err)
@@ -96,7 +97,7 @@ func (s *Storage) GoogleReaderUserGetIntegration(username string) (*model.Integr
 	`
 
 	err := s.db.QueryRow(query, username).Scan(&integration.UserID, &integration.GoogleReaderEnabled, &integration.GoogleReaderUsername, &integration.GoogleReaderPassword)
-	if err == sql.ErrNoRows {
+	if errors.Is(err, sql.ErrNoRows) {
 		return &integration, fmt.Errorf(`store: unable to find this user: %s`, username)
 	} else if err != nil {
 		return &integration, fmt.Errorf(`store: unable to fetch user: %v`, err)
@@ -362,7 +363,7 @@ func (s *Storage) Integration(userID int64) (*model.Integration, error) {
 		&integration.ArchiveorgEnabled,
 	)
 	switch {
-	case err == sql.ErrNoRows:
+	case errors.Is(err, sql.ErrNoRows):
 		return &integration, nil
 	case err != nil:
 		return &integration, fmt.Errorf(`store: unable to fetch integration row: %v`, err)

+ 4 - 3
internal/storage/user.go

@@ -5,6 +5,7 @@ package storage // import "miniflux.app/v2/internal/storage"
 
 import (
 	"database/sql"
+	"errors"
 	"fmt"
 	"strings"
 
@@ -556,7 +557,7 @@ func (s *Storage) fetchUser(query string, args ...any) (*model.User, error) {
 		&user.OpenExternalLinksInNewTab,
 	)
 
-	if err == sql.ErrNoRows {
+	if errors.Is(err, sql.ErrNoRows) {
 		return nil, nil
 	} else if err != nil {
 		return nil, fmt.Errorf(`store: unable to fetch user: %v`, err)
@@ -671,7 +672,7 @@ func (s *Storage) CheckPassword(username, password string) error {
 	username = strings.ToLower(username)
 
 	err := s.db.QueryRow("SELECT password FROM users WHERE username=$1", username).Scan(&hash)
-	if err == sql.ErrNoRows {
+	if errors.Is(err, sql.ErrNoRows) {
 		return fmt.Errorf(`store: unable to find this user: %s`, username)
 	} else if err != nil {
 		return fmt.Errorf(`store: unable to fetch user: %v`, err)
@@ -690,7 +691,7 @@ func (s *Storage) HasPassword(userID int64) (bool, error) {
 	query := `SELECT true FROM users WHERE id=$1 AND password <> '' LIMIT 1`
 
 	err := s.db.QueryRow(query, userID).Scan(&result)
-	if err == sql.ErrNoRows {
+	if errors.Is(err, sql.ErrNoRows) {
 		return false, nil
 	} else if err != nil {
 		return false, fmt.Errorf(`store: unable to execute query: %v`, err)