Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(WIP)Implement Lab 07 : Custom Errors #664

Closed
wants to merge 3 commits into from

Conversation

sirigithub
Copy link
Collaborator

@sirigithub sirigithub commented Sep 15, 2019

Fixes #665

Review of colleague's PR TBD

Changes proposed in this PR:

  • Create an executable go program in directory 07_errors/sirigithub
  • Copy the CRUD puppy from upstream master 06_puppy/sirigithub
  • Add a custom error type Error with fields Message and Code
  • Extend the Storer interface for all methods to also return error
  • Create errors for:
    • Value < 0
    • ID not found in Read, Update and Delete

@codecov
Copy link

codecov bot commented Sep 16, 2019

Codecov Report

Merging #664 into master will not change coverage.
The diff coverage is 100%.

Impacted file tree graph

@@          Coverage Diff          @@
##           master   #664   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files         234    238    +4     
  Lines        4613   4681   +68     
=====================================
+ Hits         4613   4681   +68
Impacted Files Coverage Δ
07_errors/sirigithub/main.go 100% <100%> (ø)
07_errors/sirigithub/error.go 100% <100%> (ø)
07_errors/sirigithub/mapstore.go 100% <100%> (ø)
07_errors/sirigithub/syncstore.go 100% <100%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 95053ed...764caf2. Read the comment docs.

@sirigithub sirigithub changed the title Implement Lab 07 : Custom Errors (WIP)Implement Lab 07 : Custom Errors Sep 17, 2019
return nil
}

func dbConn(dbfilePath string) (db *leveldb.DB) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dbConn - dbfilePath is unused (from unparam)

ErrIDNotFound = 404
ErrMarshallData = 400
ErrUrmarshallData = 400
ErrDatabaseConn = 500

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ErrDatabaseConn is unused (from deadcode)

ErrUrmarshallData = 400
ErrDatabaseConn = 500
ErrDatabaseWrite = 500
ErrDatabaseRead = 500

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ErrDatabaseRead is unused (from deadcode)

currID int
}

func NewdbStore(filePath string) *dbStore {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported func NewdbStore returns unexported type *main.dbStore, which can be annoying to use (from golint)

Copy link
Contributor

@camscale camscale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking around the open PRs and found this. While I know you still have it WIP, I thought I'd make a couple of relevant comments. The course is closed now so no need to make these changes - they're just comments for your info.

func NewdbStore(filePath string) *dbStore {
var store = dbStore{}
store.dbfilePath = filePath
return &store
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can implement this function with a single statement:

return &dbStore{dbfilePath: filePath}

However, it would probably be better to open the database when the dbStore is created, and add a Close() error method so the caller can close it later (which implements the io.Closer interface:

type dbStore struct {
  conn *db.leveldb.DB
  currID int
}

func NewdbStore(filePath string) *dbStore {
    return &dbStore{conn: dbConn(filePath)} // one day I'll handle errors here :-)
}

func (s *dbStore) Close() error {
    return s.conn.Close()
}

But you'll also need a different approach for currID. Because the database is persistent, if the process restarts, you start allocating IDs from 1 again. These will conflict with existing IDs.

A different approach is to use github.com/google/uuid to generate random IDs. That way do you not need to maintain any state to allocate IDs.

value := getPuppyData(puppy)
err := db.Put([]byte(strconv.Itoa(puppy.ID)), value, nil)
if err != nil {
return -1, NewError(ErrDatabaseWrite, fmt.Sprintf("Error creating Puppy %d in the dbStore", puppy.ID))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally you always want to wrap errors so you don't lose any detail so I'd write NewError() to take third error parameter (which can be nil) and store that error in your error type. See more detail below.

type Error struct {
Message string
Code int
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you will often wrap other errors, I would include an err error field here too so you can store the error returned from leveldb.

)

func (e *Error) Error() string {
return fmt.Sprintf("Error code %d: %s", e.Code, e.Message)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with the err field, this would be fmt.Sprintf("error code %d: %s: %v", e.Code, e.Message, e.err)

Note that I've made the first letter lower case as per https://github.com/golang/go/wiki/CodeReviewComments#error-strings

value := getPuppyData(puppy)
err := db.Put([]byte(strconv.Itoa(puppy.ID)), value, nil)
if err != nil {
return -1, NewError(ErrDatabaseWrite, fmt.Sprintf("Error creating Puppy %d in the dbStore", puppy.ID))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@juliaogris
Copy link
Contributor

The go-course is now closed. Thank you very much for participating.

@juliaogris juliaogris closed this Feb 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lab7 -Errors
5 participants