veyron/services/store: Use verror instead of Go errors.
Change-Id: I7508ac1dd573cf0116b9006e8105bf4fe1458637
diff --git a/services/store/memstore/log.go b/services/store/memstore/log.go
index 0aaf460..3b69326 100644
--- a/services/store/memstore/log.go
+++ b/services/store/memstore/log.go
@@ -12,7 +12,6 @@
// There are separate interfaces for reading writing; *wlog is used for writing,
// and *rlog is used for reading.
import (
- "errors"
"io"
"os"
"path"
@@ -23,6 +22,7 @@
"veyron/services/store/memstore/state"
"veyron2/security"
+ "veyron2/verror"
"veyron2/vom"
)
@@ -34,7 +34,7 @@
)
var (
- errLogIsClosed = errors.New("log is closed")
+ errLogIsClosed = verror.Abortedf("log is closed")
)
// wlog is the type of log writers.
diff --git a/services/store/memstore/pathregex/parser.go b/services/store/memstore/pathregex/parser.go
index ae45194..101cce1 100644
--- a/services/store/memstore/pathregex/parser.go
+++ b/services/store/memstore/pathregex/parser.go
@@ -2,10 +2,11 @@
import (
"bytes"
- "fmt"
"io"
"regexp"
"strings"
+
+ "veyron2/verror"
)
// parser is a recursive-descent parser for path regular expressions.
@@ -47,7 +48,7 @@
re := p.parsePath()
if p.isErrored || p.reader.Len() != 0 {
pos, _ := p.reader.Seek(0, 1)
- err := fmt.Errorf("Syntax error at char %d: %q", pos, s)
+ err := verror.BadArgf("Syntax error at char %d: %q", pos, s)
return nil, err
}
return re, nil
diff --git a/services/store/memstore/state/log.go b/services/store/memstore/state/log.go
index afee1ea..68aea9c 100644
--- a/services/store/memstore/state/log.go
+++ b/services/store/memstore/state/log.go
@@ -1,11 +1,10 @@
package state
import (
- "errors"
-
"veyron/services/store/memstore/refs"
"veyron2/storage"
+ "veyron2/verror"
"veyron2/vom"
)
@@ -16,7 +15,7 @@
)
var (
- errUnsupportedLogVersion = errors.New("unsupported log version")
+ errUnsupportedLogVersion = verror.Internalf("unsupported log version")
)
// header contains the meta-information for a log file.
diff --git a/services/store/memstore/state/mutable_snapshot.go b/services/store/memstore/state/mutable_snapshot.go
index 08e923d..c5a8b11 100644
--- a/services/store/memstore/state/mutable_snapshot.go
+++ b/services/store/memstore/state/mutable_snapshot.go
@@ -1,7 +1,6 @@
package state
import (
- "errors"
"fmt"
"veyron/services/store/memstore/acl"
@@ -12,6 +11,7 @@
"veyron/runtimes/google/lib/functional"
"veyron2/security"
"veyron2/storage"
+ "veyron2/verror"
)
// MutableSnapshot is a mutable version of the snapshot. It contains a Snapshot
@@ -103,17 +103,14 @@
}
var (
- // TODO(tilaks): don't expose errors, use verror instead.
- ErrBadPath = errors.New("malformed path")
- ErrTypeMismatch = errors.New("type mismatch")
- ErrNotFound = errors.New("not found")
- ErrBadRef = errors.New("value has dangling references")
- ErrCantUnlinkByID = errors.New("can't unlink entries by ID")
- ErrPreconditionFailed = errors.New("precondition failed")
- ErrIDsDoNotMatch = errors.New("IDs do not match")
- ErrPermissionDenied = errors.New("permission denied") // TODO(tilaks): can permission denied leak store structure?
- ErrNotTagList = errors.New("not a TagList")
- ErrDuplicatePutMutation = errors.New("duplicate calls to PutMutation for the same ID")
+ errBadPath = verror.BadArgf("malformed path")
+ errBadRef = verror.BadArgf("value has dangling references")
+ errCantUnlinkByID = verror.BadArgf("can't unlink entries by ID")
+ errDuplicatePutMutation = verror.BadArgf("duplicate calls to PutMutation for the same ID")
+ errNotFound = verror.NotFoundf("not found")
+ errNotTagList = verror.BadArgf("not a TagList")
+ errPermissionDenied = verror.NotAuthorizedf("")
+ errPreconditionFailed = verror.Abortedf("precondition failed")
nullID storage.ID
)
@@ -264,7 +261,7 @@
}
c.setRefs()
if !sn.refsExist(c.refs) {
- return nil, ErrBadRef
+ return nil, errBadRef
}
sn.put(c)
sn.addRefs(id, c.refs)
@@ -280,13 +277,13 @@
// replaceValue updates the cell.value.
func (sn *MutableSnapshot) replaceValue(checker *acl.Checker, c *Cell, v interface{}) (*Cell, error) {
if !checker.IsAllowed(security.WriteLabel) {
- return nil, ErrPermissionDenied
+ return nil, errPermissionDenied
}
cp := *c
cp.Value = v
cp.setRefs()
if !sn.refsExist(cp.refs) {
- return nil, ErrBadRef
+ return nil, errBadRef
}
sn.put(&cp)
sn.updateRefs(c.ID, c.refs, cp.refs)
@@ -296,13 +293,13 @@
// replaceDir updates the cell.dir.
func (sn *MutableSnapshot) replaceDir(checker *acl.Checker, c *Cell, d functional.Set) (*Cell, error) {
if !checker.IsAllowed(security.WriteLabel) {
- return nil, ErrPermissionDenied
+ return nil, errPermissionDenied
}
cp := *c
cp.Dir = d
cp.setRefs()
if !sn.refsExist(cp.refs) {
- return nil, ErrBadRef
+ return nil, errBadRef
}
sn.put(&cp)
sn.updateRefs(c.ID, c.refs, cp.refs)
@@ -312,13 +309,13 @@
// replaceTags replaces the cell.tags.
func (sn *MutableSnapshot) replaceTags(checker *acl.Checker, c *Cell, tags storage.TagList) (*Cell, error) {
if !checker.IsAllowed(security.AdminLabel) {
- return nil, ErrPermissionDenied
+ return nil, errPermissionDenied
}
cp := *c
cp.Tags = tags
cp.setRefs()
if !sn.refsExist(cp.refs) {
- return nil, ErrBadRef
+ return nil, errBadRef
}
sn.put(&cp)
sn.updateRefs(c.ID, c.refs, cp.refs)
@@ -351,7 +348,7 @@
checker := sn.newPermChecker(pid)
cell, suffix, v := sn.resolveCell(checker, path, sn.mutations)
if cell == nil {
- return nil, ErrNotFound
+ return nil, errNotFound
}
var e *storage.Entry
if len(suffix) == 0 {
@@ -394,7 +391,7 @@
// Find the parent object.
c, suffix, _ := sn.resolveCell(checker, path[:len(path)-1], sn.mutations)
if c == nil {
- return nil, ErrNotFound
+ return nil, errNotFound
}
if len(suffix) > 0 && suffix[0] == refs.TagsDirName {
return sn.putTagsValue(checker, path, suffix[1:], c, v)
@@ -402,7 +399,7 @@
value := deepcopy(c.Value)
p, s := field.Get(makeInnerReference(value), suffix)
if len(s) != 0 {
- return nil, ErrNotFound
+ return nil, errNotFound
}
// Add value to the parent.
@@ -411,7 +408,7 @@
switch result {
case field.SetFailed:
if len(suffix) != 0 {
- return nil, ErrNotFound
+ return nil, errNotFound
}
if name == refs.TagsDirName {
return sn.putTags(checker, c, v)
@@ -438,7 +435,7 @@
tags := deepcopy(c.Tags).(storage.TagList)
p, s := field.Get(&tags, suffix)
if len(s) != 0 {
- return nil, ErrNotFound
+ return nil, errNotFound
}
// Add value to the parent.
@@ -446,7 +443,7 @@
result, id := field.Set(p, name, v)
switch result {
case field.SetFailed:
- return nil, ErrNotFound
+ return nil, errNotFound
case field.SetAsID:
nc, err := sn.add(checker, id, v)
if err != nil {
@@ -467,7 +464,7 @@
func (sn *MutableSnapshot) putTags(checker *acl.Checker, c *Cell, v interface{}) (*Cell, error) {
tags, ok := v.(storage.TagList)
if !ok {
- return nil, ErrNotTagList
+ return nil, errNotTagList
}
return sn.replaceTags(checker, c, tags)
}
@@ -478,7 +475,7 @@
if id, ok := v.(storage.ID); ok {
ncell := sn.Find(id)
if ncell == nil {
- return nil, ErrNotFound
+ return nil, errNotFound
}
r.ID = id
dir := c.Dir.Put(r)
@@ -513,7 +510,7 @@
// putRoot replaces the root.
func (sn *MutableSnapshot) putRoot(checker *acl.Checker, v interface{}) (*Cell, error) {
if !checker.IsAllowed(security.WriteLabel) {
- return nil, ErrPermissionDenied
+ return nil, errPermissionDenied
}
id := sn.rootID
@@ -542,7 +539,7 @@
func (sn *MutableSnapshot) putValueByID(checker *acl.Checker, id storage.ID, v interface{}) (*Cell, error) {
checker.Update(uidTagList)
if !checker.IsAllowed(security.WriteLabel) {
- return nil, ErrPermissionDenied
+ return nil, errPermissionDenied
}
sn.gc()
@@ -554,7 +551,7 @@
checker := sn.newPermChecker(pid)
if path.IsRoot() {
if !checker.IsAllowed(security.WriteLabel) {
- return ErrPermissionDenied
+ return errPermissionDenied
}
sn.unref(sn.rootID)
sn.rootID = nullID
@@ -563,13 +560,13 @@
return nil
}
if path.IsStrictID() {
- return ErrCantUnlinkByID
+ return errCantUnlinkByID
}
// Split the names into directory and field parts.
cell, suffix, _ := sn.resolveCell(checker, path[:len(path)-1], sn.mutations)
if cell == nil {
- return ErrNotFound
+ return errNotFound
}
// Remove the field.
@@ -586,7 +583,7 @@
value := deepcopy(cell.Value)
p, _ := field.Get(value, suffix)
if !field.Remove(p, name) {
- return ErrNotFound
+ return errNotFound
}
_, err := sn.replaceValue(checker, cell, value)
@@ -600,7 +597,7 @@
id := extmu.ID
// Check that a mutation has not already been put for this id.
if _, ok := mus.Delta[id]; ok {
- return ErrDuplicatePutMutation
+ return errDuplicatePutMutation
}
// If the object has no version, it was deleted.
if extmu.Version == storage.NoVersion {
diff --git a/services/store/memstore/state/mutable_snapshot_test.go b/services/store/memstore/state/mutable_snapshot_test.go
index 5651b70..1930ff1 100644
--- a/services/store/memstore/state/mutable_snapshot_test.go
+++ b/services/store/memstore/state/mutable_snapshot_test.go
@@ -8,6 +8,7 @@
"veyron/services/store/memstore/refs"
"veyron2/storage"
+ "veyron2/verror"
"veyron2/vom"
)
@@ -198,8 +199,8 @@
// Not possible to create a Dir with a dangling reference.
d := &Dir{Entries: map[string]storage.ID{"ref": storage.NewID()}}
- if _, err := sn.Put(rootPublicID, ePath, d); err != ErrBadRef {
- t.Errorf("Error should be %q: got %q", ErrBadRef, err)
+ if _, err := sn.Put(rootPublicID, ePath, d); !verror.Is(err, verror.BadArg) {
+ t.Errorf("Error should be %v: got %v", verror.BadArg, err)
}
// Set the Ref to refer to the root.
diff --git a/services/store/memstore/state/snapshot.go b/services/store/memstore/state/snapshot.go
index 6c4b613..fd3a032 100644
--- a/services/store/memstore/state/snapshot.go
+++ b/services/store/memstore/state/snapshot.go
@@ -94,7 +94,7 @@
// Pass nil for 'mutations' since the snapshot is immutable.
cell, suffix, v := sn.resolveCell(checker, path, nil)
if cell == nil {
- return nil, ErrNotFound
+ return nil, errNotFound
}
var e *storage.Entry
if len(suffix) == 0 {
@@ -139,7 +139,7 @@
if len(path) > 0 && path[0] == refs.TagsDirName {
if !checker.IsAllowed(security.AdminLabel) {
// Access to .tags requires admin priviledges.
- return nil, nil, ErrPermissionDenied
+ return nil, nil, errPermissionDenied
}
v, suffix = field.Get(cell.Tags, path[1:])
} else {
diff --git a/services/store/memstore/state/state.go b/services/store/memstore/state/state.go
index a1cd56c..04f914c 100644
--- a/services/store/memstore/state/state.go
+++ b/services/store/memstore/state/state.go
@@ -106,14 +106,14 @@
// is 0 and the cell already exists, or pre is not 0 and the cell does
// not already exist or have the expected version.
if pre == 0 && ok || pre != 0 && (!ok || c.(*Cell).Version != pre) {
- return ErrPreconditionFailed
+ return errPreconditionFailed
}
}
for id, pre := range mu.Deletions {
c, ok := table.Get(&Cell{ID: id})
// The target is not required to exist.
if ok && c.(*Cell).Version != pre {
- return ErrPreconditionFailed
+ return errPreconditionFailed
}
}
diff --git a/services/store/memstore/store.go b/services/store/memstore/store.go
index a4397b0..7a6202d 100644
--- a/services/store/memstore/store.go
+++ b/services/store/memstore/store.go
@@ -1,7 +1,6 @@
package memstore
import (
- "errors"
"io"
"veyron/runtimes/google/lib/sync"
@@ -13,6 +12,7 @@
"veyron2/ipc"
"veyron2/security"
"veyron2/storage"
+ "veyron2/verror"
)
// Store is the in-memory state of the store.
@@ -31,7 +31,7 @@
var _ service.Store = (*Store)(nil)
var (
- ErrRequestCancelled = errors.New("request cancelled")
+ ErrRequestCancelled = verror.Abortedf("request cancelled")
)
// New creates a new store. admin is the public ID of the administrator, dbName
diff --git a/services/store/memstore/store_test.go b/services/store/memstore/store_test.go
index fa9723a..a71aa48 100644
--- a/services/store/memstore/store_test.go
+++ b/services/store/memstore/store_test.go
@@ -5,11 +5,11 @@
"os"
"testing"
- "veyron/services/store/memstore/state"
storetesting "veyron/services/store/memstore/testing"
"veyron/services/store/raw"
"veyron2/storage"
+ "veyron2/verror"
)
func TestLogWrite(t *testing.T) {
@@ -86,8 +86,8 @@
st.log.close()
// Commit the state. The call should fail.
- if err := st.log.appendTransaction(nil); err != errLogIsClosed {
- t.Errorf("Expected error %q, got %q", errLogIsClosed, err)
+ if err := st.log.appendTransaction(nil); !verror.Is(err, verror.Aborted) {
+ t.Errorf("Expected error %v, got %v", verror.Aborted, err)
}
}
@@ -293,8 +293,8 @@
Value: v2,
Dir: empty,
})
- if err := s.Finish(); err != state.ErrPreconditionFailed {
- t.Fatalf("Expected precondition to fail")
+ if err := s.Finish(); !verror.Is(err, verror.Aborted) {
+ t.Errorf("Error should be %v: got %v", verror.Aborted, err)
}
}
@@ -330,8 +330,8 @@
Value: "v2",
Dir: empty,
})
- if err := s.Finish(); err != state.ErrDuplicatePutMutation {
- t.Fatalf("Expected precondition to fail")
+ if err := s.Finish(); !verror.Is(err, verror.BadArg) {
+ t.Errorf("Error should be %v: got %v", verror.BadArg, err)
}
}
@@ -358,8 +358,8 @@
Dir: empty,
})
s.Cancel()
- if err := s.Finish(); err != ErrRequestCancelled {
- t.Fatalf("Expected request to be cancelled")
+ if err := s.Finish(); !verror.Is(err, verror.Aborted) {
+ t.Errorf("Error should be %v: got %v", verror.Aborted, err)
}
expectNotExists(t, st, nil, "/")
diff --git a/services/store/memstore/transaction.go b/services/store/memstore/transaction.go
index 5328457..bb82a34 100644
--- a/services/store/memstore/transaction.go
+++ b/services/store/memstore/transaction.go
@@ -1,11 +1,11 @@
package memstore
import (
- "errors"
"sync"
"veyron/services/store/memstore/state"
"veyron/services/store/service"
+ "veyron2/verror"
)
// Transaction is the type of transactions. Each transaction has a snapshot of
@@ -22,7 +22,7 @@
}
var (
- errBadTransaction = errors.New("bad transaction")
+ errBadTransaction = verror.BadArgf("bad transaction")
)
// newNilTransaction is used when nil is passed in as the transaction for an
diff --git a/services/store/memstore/watch/glob_processor.go b/services/store/memstore/watch/glob_processor.go
index 38ea6c1..6254a17 100644
--- a/services/store/memstore/watch/glob_processor.go
+++ b/services/store/memstore/watch/glob_processor.go
@@ -1,8 +1,6 @@
package watch
import (
- "errors"
-
iquery "veyron/services/store/memstore/query"
"veyron/services/store/memstore/state"
@@ -42,7 +40,7 @@
func (p *globProcessor) processState(st *state.State) ([]watch.Change, error) {
// Check that the initial state has not already been processed.
if p.hasProcessedState {
- return nil, errors.New("cannot process state after processing the initial state")
+ return nil, errInitialStateAlreadyProcessed
}
p.hasProcessedState = true
@@ -76,7 +74,7 @@
func (p *globProcessor) processTransaction(mus *state.Mutations) ([]watch.Change, error) {
// Ensure that the initial state has been processed.
if !p.hasProcessedState {
- return nil, errors.New("cannot process a transaction before processing the initial state")
+ return nil, errInitialStateNotProcessed
}
previousMatches := p.matches
diff --git a/services/store/memstore/watch/processor.go b/services/store/memstore/watch/processor.go
index ab9bb69..ce3e07e 100644
--- a/services/store/memstore/watch/processor.go
+++ b/services/store/memstore/watch/processor.go
@@ -3,6 +3,12 @@
import (
"veyron/services/store/memstore/state"
"veyron2/services/watch"
+ "veyron2/verror"
+)
+
+var (
+ errInitialStateAlreadyProcessed = verror.Internalf("cannot process state after processing the initial state")
+ errInitialStateNotProcessed = verror.Internalf("cannot process a transaction before processing the initial state")
)
// reqProcessor processes log entries into watch changes. At first,
diff --git a/services/store/memstore/watch/raw_processor.go b/services/store/memstore/watch/raw_processor.go
index 7781c48..a783caf 100644
--- a/services/store/memstore/watch/raw_processor.go
+++ b/services/store/memstore/watch/raw_processor.go
@@ -1,7 +1,6 @@
package watch
import (
- "errors"
"fmt"
"veyron/services/store/memstore/refs"
@@ -11,6 +10,7 @@
"veyron2/security"
"veyron2/services/watch"
"veyron2/storage"
+ "veyron2/verror"
)
var (
@@ -50,7 +50,7 @@
func (p *rawProcessor) processState(st *state.State) ([]watch.Change, error) {
// Check that the initial state has not already been processed.
if p.hasProcessedState {
- return nil, errors.New("cannot process state after processing the initial state")
+ return nil, errInitialStateAlreadyProcessed
}
p.hasProcessedState = true
@@ -100,7 +100,7 @@
func (p *rawProcessor) processTransaction(mus *state.Mutations) ([]watch.Change, error) {
// Ensure that the initial state has been processed.
if !p.hasProcessedState {
- return nil, errors.New("cannot process a transaction before processing the initial state")
+ return nil, errInitialStateNotProcessed
}
// If the root was deleted, add extra space for a prepared deletion.
@@ -207,7 +207,7 @@
// does not have a root, nullID is returned.
func rootID(pid security.PublicID, sn *state.MutableSnapshot) (storage.ID, error) {
entry, err := sn.Get(pid, rootPath)
- if err == state.ErrNotFound {
+ if verror.Is(err, verror.NotFound) {
return nullID, nil
}
if err != nil {
diff --git a/services/store/memstore/watch/watcher.go b/services/store/memstore/watch/watcher.go
index 4cf8562..ad1ae00 100644
--- a/services/store/memstore/watch/watcher.go
+++ b/services/store/memstore/watch/watcher.go
@@ -3,7 +3,6 @@
import (
"bytes"
"encoding/binary"
- "errors"
"io"
"time"
@@ -20,8 +19,8 @@
)
var (
- ErrWatchClosed = io.EOF
- ErrUnknownResumeMarker = errors.New("Unknown ResumeMarker")
+ errWatchClosed = io.EOF
+ errUnknownResumeMarker = verror.BadArgf("Unknown ResumeMarker")
nowResumeMarker = []byte("now") // UTF-8 conversion.
initialStateSkippedChange = watch.Change{
Name: "",
@@ -104,7 +103,7 @@
done := make(chan error, 1)
if !w.pending.TryAdd() {
- return ErrWatchClosed
+ return errWatchClosed
}
// This goroutine does not leak because processRequest is always terminated.
go func() {
@@ -122,7 +121,7 @@
case <-w.closed:
case <-ctx.Closed():
}
- return ErrWatchClosed
+ return errWatchClosed
}
func (w *watcher) processRequest(cancel <-chan struct{}, processor reqProcessor,
@@ -251,7 +250,7 @@
return &onOrAfterFilter{baseFilter{uint64(time.Now().UnixNano()), false}}, nil
}
if len(resumeMarker) != 8 {
- return nil, ErrUnknownResumeMarker
+ return nil, errUnknownResumeMarker
}
return &onAndAfterFilter{baseFilter{binary.BigEndian.Uint64(resumeMarker), false}}, nil
}
@@ -276,7 +275,7 @@
return false, nil
}
if timestamp > f.initialTimestamp {
- return false, ErrUnknownResumeMarker
+ return false, errUnknownResumeMarker
}
// TODO(tilaks): if the most recent timestamp in the log is less than
// initialTimestamp, return ErrUnknownResumeMarker.
diff --git a/services/store/memstore/watch/watcher_test.go b/services/store/memstore/watch/watcher_test.go
index 4ce82aa..8ef6878 100644
--- a/services/store/memstore/watch/watcher_test.go
+++ b/services/store/memstore/watch/watcher_test.go
@@ -13,6 +13,7 @@
"veyron2/services/watch"
"veyron2/storage"
+ "veyron2/verror"
)
func TestWatchRaw(t *testing.T) {
@@ -474,8 +475,8 @@
ws := watchtesting.WatchRaw(rootPublicID, w.WatchRaw, req)
// The resume marker should be unknown.
- if err := ws.Finish(); err != ErrUnknownResumeMarker {
- t.Errorf("Unexpected error: %v", err)
+ if err := ws.Finish(); !verror.Is(err, verror.BadArg) {
+ t.Errorf("Error should be %v: got %v", verror.BadArg, err)
}
// Start a watch request with a resume marker that's too late.
@@ -484,8 +485,8 @@
ws = watchtesting.WatchRaw(rootPublicID, w.WatchRaw, req)
// The resume marker should be unknown.
- if err := ws.Finish(); err != ErrUnknownResumeMarker {
- t.Errorf("Unexpected error: %v", err)
+ if err := ws.Finish(); !verror.Is(err, verror.BadArg) {
+ t.Errorf("Error should be %v: got %v", verror.BadArg, err)
}
}
diff --git a/services/store/server/object.go b/services/store/server/object.go
index 8f9b02c..dd33bb6 100644
--- a/services/store/server/object.go
+++ b/services/store/server/object.go
@@ -1,8 +1,6 @@
package server
import (
- "errors"
-
"veyron/services/store/service"
"veyron2/ipc"
@@ -12,6 +10,7 @@
"veyron2/services/watch"
"veyron2/storage"
"veyron2/vdl/vdlutil"
+ "veyron2/verror"
)
type object struct {
@@ -21,8 +20,8 @@
}
var (
- errNotAValue = errors.New("not a storage.Value")
- errNotAnAttribute = errors.New("not a storage.Attr")
+ errNotAValue = verror.BadArgf("not a storage.Value")
+ errNotAnAttribute = verror.BadArgf("not a storage.Attr")
_ store.ObjectService = (*object)(nil)
diff --git a/services/store/server/server.go b/services/store/server/server.go
index 7b37e6e..8eb4478 100644
--- a/services/store/server/server.go
+++ b/services/store/server/server.go
@@ -2,7 +2,6 @@
package server
import (
- "errors"
"reflect"
"strings"
"sync"
@@ -34,10 +33,10 @@
nullTransactionID store.TransactionID
- errTransactionAlreadyExists = errors.New("transaction already exists")
- errTransactionDoesNotExist = errors.New("transaction does not exist")
+ errTransactionAlreadyExists = verror.Existsf("transaction already exists")
+ errTransactionDoesNotExist = verror.NotFoundf("transaction does not exist")
// Transaction exists, but may not be used by the caller.
- errPermissionDenied = errors.New("permission denied")
+ errPermissionDenied = verror.NotAuthorizedf("permission denied")
)
// Server stores the dictionary of all media items. It has a scanner.Scanner