Skip to content

Commit

Permalink
feat: wrapping errors in library with more information (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanHope committed Nov 14, 2023
1 parent c316b1d commit a9b0cfc
Show file tree
Hide file tree
Showing 14 changed files with 160 additions and 104 deletions.
24 changes: 13 additions & 11 deletions lib/add_book.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package lib

import (
"fmt"

"github.com/samber/lo"
)

Expand Down Expand Up @@ -54,54 +56,54 @@ func AddBook(url string, options addBookOptions) (Book, error) {
}

if err := validateURL(NullStringFrom(url)); err != nil {
return book, err
return book, fmt.Errorf("URL validation failed while adding bookmark: %w", err)
}

if err := validateName(options.name); err != nil {
return book, err
return book, fmt.Errorf("name validation failed while adding bookmark: %w", err)
}

if err := validateDescription(options.description); err != nil {
return book, err
return book, fmt.Errorf("description validation failed while adding bookmark: %w", err)
}

if err := validateParentID(tx, options.parentID); err != nil {
return book, err
return book, fmt.Errorf("parent ID validation failed while adding bookmark: %w", err)
}

if err := validateTags(options.tags, make([]string, 0)); err != nil {
return book, err
return book, fmt.Errorf("tags validation failed while adding bookmark: %w", err)
}

id, err := addBookDB(tx, url, options.name.String, options.description, options.parentID)
if err != nil {
return book, err
return book, fmt.Errorf("error while adding bookmark: %w", err)
}

existingTags, err := getTagsDB(tx, getTagsDBArgs{
tagsFilter: options.tags,
})
if err != nil {
return book, err
return book, fmt.Errorf("error getting tags while adding bookmark: %w", err)
}

tagsToAdd, _ := lo.Difference(options.tags, existingTags)
if err = addTagsDB(tx, tagsToAdd); err != nil {
return book, err
return book, fmt.Errorf("error adding tags while adding bookmark: %w", err)
}

if err = linkTagsDB(tx, id, options.tags); err != nil {
return book, err
return book, fmt.Errorf("error linking tags while adding bookmark: %w", err)
}

books, err := getBooksDB(tx, getBooksDBArgs{
idFilter: id,
includeBooks: true,
})
if err != nil {
return book, err
return book, fmt.Errorf("error getting bookmarks while adding bookmark: %w", err)
}

return books[0], err
return books[0], nil
})
}
14 changes: 9 additions & 5 deletions lib/add_folder.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package lib

import (
"fmt"
)

// addFolderOptions are the optional arguments for AddFolder.
type addFolderOptions struct {
db NullString
Expand Down Expand Up @@ -27,26 +31,26 @@ func AddFolder(name string, options addFolderOptions) (Book, error) {
var book Book

if err := validateName(NullStringFrom(name)); err != nil {
return book, err
return book, fmt.Errorf("name validation failed while adding folder: %w", err)
}

if err := validateParentID(tx, options.parentID); err != nil {
return book, err
return book, fmt.Errorf("parent ID validation failed while adding folder: %w", err)
}

id, err := addFolderDB(tx, name, options.parentID)
if err != nil {
return book, err
return book, fmt.Errorf("error while adding folder: %w", err)
}

books, err := getBooksDB(tx, getBooksDBArgs{
idFilter: id,
includeFolders: true,
})
if err != nil {
return book, err
return book, fmt.Errorf("error getting folders while adding folder: %w", err)
}

return books[0], err
return books[0], nil
})
}
12 changes: 7 additions & 5 deletions lib/add_tags.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package lib

import (
"fmt"

"github.com/samber/lo"
)

Expand Down Expand Up @@ -29,15 +31,15 @@ func AddTags(id string, tags []string, options addTagsOptions) (Book, error) {
includeBooks: true,
})
if err != nil {
return book, err
return book, fmt.Errorf("error getting tags while adding tags: %w", err)
}

if len(books) != 1 || books[0].IsFolder {
return book, ErrBookNotFound
}

if err := validateTags(tags, books[0].Tags); err != nil {
return book, err
return book, fmt.Errorf("tags validation failed while adding tags: %w", err)
}

existingTags, err := getTagsDB(tx, getTagsDBArgs{
Expand All @@ -49,19 +51,19 @@ func AddTags(id string, tags []string, options addTagsOptions) (Book, error) {

tagsToAdd, _ := lo.Difference(tags, existingTags)
if err = addTagsDB(tx, tagsToAdd); err != nil {
return book, err
return book, fmt.Errorf("error while adding tags: %w", err)
}

if err = linkTagsDB(tx, id, tags); err != nil {
return book, err
return book, fmt.Errorf("error linking tags while adding tags: %w", err)
}

books, err = getBooksDB(tx, getBooksDBArgs{
idFilter: id,
includeBooks: true,
})
if err != nil {
return book, err
return book, fmt.Errorf("error getting bookmarks while adding tags: %w", err)
}

return books[0], nil
Expand Down
31 changes: 16 additions & 15 deletions lib/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package lib

import (
"errors"
"fmt"
"os"
"path/filepath"
"runtime"
Expand Down Expand Up @@ -40,21 +41,21 @@ func GetConfig() (Config, error) {

configPath, err := getConfigPath(runtime.GOOS, os.UserHomeDir, filepath.Join)
if err != nil {
return config, err
return config, fmt.Errorf("error getting config path while getting config: %w", err)
}

var k = koanf.New(".")
if err := k.Load(file.Provider(configPath), toml.Parser()); err != nil {
if strings.Contains(err.Error(), "no such file or directory") {
return config, ErrConfigMissing
} else {
return config, err
return config, fmt.Errorf("error loading config while getting config: %w", err)
}
}

err = k.Unmarshal("", &config)
if err != nil {
return config, err
return config, fmt.Errorf("error unmarshalling config while getting config: %w", err)
}

return config, nil
Expand All @@ -65,18 +66,18 @@ func GetConfig() (Config, error) {
func UpdateConfig(update updateConfigFn) error {
config, err := GetConfig()
if err != nil && !errors.Is(err, ErrConfigMissing) {
return err
return fmt.Errorf("error getting config while updating config: %w", err)
}

if errors.Is(err, ErrConfigMissing) {
folder, err := getFolderPath(runtime.GOOS, os.UserHomeDir, filepath.Join)
if err != nil {
return err
return fmt.Errorf("error getting config folder path while updating config: %w", err)
}

err = os.MkdirAll(folder, os.ModePerm)
if err != nil {
return err
return fmt.Errorf("error making config folder while updating config: %w", err)
}
}

Expand All @@ -85,28 +86,28 @@ func UpdateConfig(update updateConfigFn) error {
var k = koanf.New(".")
err = k.Load(structs.Provider(config, "koanf"), nil)
if err != nil {
return err
return fmt.Errorf("error loading config while updating config: %w", err)
}

buffer, err := k.Marshal(toml.Parser())
if err != nil {
return err
return fmt.Errorf("error marshalling config while updating config: %w", err)
}

configPath, err := getConfigPath(runtime.GOOS, os.UserHomeDir, filepath.Join)
if err != nil {
return err
return fmt.Errorf("error getting config path while updating config: %w", err)
}

handle, err := os.Create(configPath)
if err != nil {
return err
return fmt.Errorf("error creating config file while updating config: %w", err)
}
defer handle.Close()

_, err = handle.Write(buffer)
if err != nil {
return err
return fmt.Errorf("error writing config file contents while updating config: %w", err)
}

return nil
Expand All @@ -125,11 +126,11 @@ func getDatabasePath(inputPath NullString, configPath string, goos string, mkDir
} else {
folder, err := getFolderPath(goos, userHome, join)
if err != nil {
return "", err
return "", fmt.Errorf("error getting folder path while getting database path: %w", err)
}

if err = mkDirAll(folder, os.ModePerm); err != nil {
return "", err
return "", fmt.Errorf("error creating folder while getting database path: %w", err)
}

return join(folder, databaseFilename), nil
Expand All @@ -141,7 +142,7 @@ func getDatabasePath(inputPath NullString, configPath string, goos string, mkDir
func getConfigPath(goos string, userHome userHomeFn, join joinFn) (string, error) {
folder, err := getFolderPath(goos, userHome, join)
if err != nil {
return "", err
return "", fmt.Errorf("error getting folder path while getting config path: %w", err)
}

return join(folder, configFilename), nil
Expand All @@ -155,7 +156,7 @@ func getConfigPath(goos string, userHome userHomeFn, join joinFn) (string, error
func getFolderPath(goos string, userHome userHomeFn, join joinFn) (string, error) {
home, err := userHome()
if err != nil {
return "", err
return "", fmt.Errorf("error getting home path while getting folder path: %w", err)
}

var folder string
Expand Down
4 changes: 1 addition & 3 deletions lib/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import (
)

var (
// ErrUnexpected is returned when an unexpected error occurs.
ErrUnexpected = errors.New("unexpected error")
// ErrNoUpdate is returned when an update is requested with no updates.
ErrNoUpdate = errors.New("no update")
// ErrBookNotFound is returned when a target bookmark was not found.
Expand Down Expand Up @@ -46,5 +44,5 @@ var (
// ErrQueryTooShort is returned when a provided query is too short.
ErrQueryTooShort = errors.New("query too short")
// ErrConfigMissing is returned when the config file is missing.
ErrConfigMissing = errors.New("config is missing")
ErrConfigMissing = errors.New("config missing")
)
19 changes: 14 additions & 5 deletions lib/list_books.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package lib

import (
"fmt"
)

// listBooksOptions are the optional arguments for ListBooks.
type listBooksOptions struct {
db NullString
Expand Down Expand Up @@ -89,22 +93,22 @@ func ListBooks(options listBooksOptions) ([]Book, error) {
}

if err := validateFirst(options.first); err != nil {
return books, err
return books, fmt.Errorf("first validation failed while listing bookmarks: %w", err)
}

if err := validateDirection(options.direction); err != nil {
return books, err
return books, fmt.Errorf("direction validation failed while listing bookmarks: %w", err)
}

if err := validateOrder(options.order); err != nil {
return books, err
return books, fmt.Errorf("order validation failed while listing bookmarks: %w", err)
}

if err := validateQuery(options.query); err != nil {
return books, err
return books, fmt.Errorf("query validation failed while listing bookmarks: %w", err)
}

return getBooksDB(tx, getBooksDBArgs{
books, err := getBooksDB(tx, getBooksDBArgs{
includeBooks: options.includeBookmarks,
includeFolders: options.includeFolders,
parentID: options.parentID,
Expand All @@ -115,5 +119,10 @@ func ListBooks(options listBooksOptions) ([]Book, error) {
direction: options.direction,
first: options.first,
})
if err != nil {
return books, fmt.Errorf("error while listing bookmarks: %w", err)
}

return books, nil
})
}
17 changes: 13 additions & 4 deletions lib/list_tags.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package lib

import (
"fmt"
)

// listTagsOptions are the optional arguments for ListTags.
type listTagsOptions struct {
db NullString
Expand Down Expand Up @@ -47,22 +51,27 @@ func ListTags(options listTagsOptions) ([]string, error) {
tags := make([]string, 0)

if err := validateFirst(options.first); err != nil {
return tags, err
return tags, fmt.Errorf("first validation failed while listing tags: %w", err)
}

if err := validateDirection(options.direction); err != nil {
return tags, err
return tags, fmt.Errorf("direction validation failed while listing tags: %w", err)
}

if err := validateQuery(options.query); err != nil {
return tags, err
return tags, fmt.Errorf("query validation failed while listing tags: %w", err)
}

return getTagsDB(tx, getTagsDBArgs{
tags, err := getTagsDB(tx, getTagsDBArgs{
query: options.query,
after: options.after,
direction: options.direction,
first: options.first,
})
if err != nil {
return tags, fmt.Errorf("error while listing tags: %w", err)
}

return tags, nil
})
}
Loading

0 comments on commit a9b0cfc

Please sign in to comment.