Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Unified Diff: go/src/infra/gae/libs/gae/upstream_errors.go

Issue 1222903002: Refactor current GAE abstraction library to be free of the SDK* (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: more fixes Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: go/src/infra/gae/libs/gae/upstream_errors.go
diff --git a/go/src/infra/gae/libs/gae/upstream_errors.go b/go/src/infra/gae/libs/gae/upstream_errors.go
new file mode 100644
index 0000000000000000000000000000000000000000..f6ebad5538ae2b3dd14ae34b0f3f6766cb8a9cf5
--- /dev/null
+++ b/go/src/infra/gae/libs/gae/upstream_errors.go
@@ -0,0 +1,109 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file contains types and values which are mirrors/duplicates of the
+// upstream SDK errors. This exists so that users can depend solely on this
+// wrapper library without also needing to import the SDK.
+//
+// Format of the errors is Err<sub>Name, where <sub> is one of the 2/3-letter
+// All Caps subpackage codes (e.g. DS, TQ, MC, etc.). Name is the same as the
+// original SDK error.
+//
+// Note that this only replicates the 'named' errors (which a user might compare
+// for equality or observe by-type in their code like ErrDSNoSuchEntity). The
+// underlying implementations can (and do) return many more sorts of non-named
+// and custom errors.
+
+package gae
+
+import (
+ "fmt"
+ "reflect"
+
+ "google.golang.org/appengine/datastore"
+ "google.golang.org/appengine/memcache"
+ "google.golang.org/appengine/taskqueue"
+)
+
+// These are pass-through versions from the managed-VM SDK. All implementations
+// must return these (exact) errors (not just an error with the same text).
+var (
+ ErrDSInvalidEntityType = datastore.ErrInvalidEntityType
+ ErrDSInvalidKey = datastore.ErrInvalidKey
+ ErrDSNoSuchEntity = datastore.ErrNoSuchEntity
+ ErrDSConcurrentTransaction = datastore.ErrConcurrentTransaction
+ ErrDSQueryDone = datastore.Done
+
+ ErrMCCacheMiss = memcache.ErrCacheMiss
+ ErrMCCASConflict = memcache.ErrCASConflict
+ ErrMCNoStats = memcache.ErrNoStats
+ ErrMCNotStored = memcache.ErrNotStored
+ ErrMCServerError = memcache.ErrServerError
+
+ ErrTQTaskAlreadyAdded = taskqueue.ErrTaskAlreadyAdded
+)
+
+/////////////////////////////// Supporting code ////////////////////////////////
+
+// MultiError is returned by batch operations when there are errors with
+// particular elements. Errors will be in a one-to-one correspondence with
+// the input elements; successful elements will have a nil entry.
+type MultiError []error
+
+func (m MultiError) Error() string {
+ s, n := "", 0
+ for _, e := range m {
+ if e != nil {
+ if n == 0 {
+ s = e.Error()
+ }
+ n++
+ }
+ }
+ switch n {
+ case 0:
+ return "(0 errors)"
+ case 1:
+ return s
+ case 2:
+ return s + " (and 1 other error)"
+ }
+ return fmt.Sprintf("%s (and %d other errors)", s, n-1)
+}
+
+// SingleError provides a simple way to uwrap a MultiError if you know that it
+// could only ever contain one element.
+//
+// If err is a MultiError, return its first element. Otherwise, return err.
+func SingleError(err error) error {
+ if me, ok := err.(MultiError); ok {
+ if len(me) == 0 {
+ return nil
+ }
+ return me[0]
+ }
+ return err
+}
+
+var (
+ multiErrorType = reflect.TypeOf(MultiError(nil))
+)
+
+// FixError will convert a backend-specific non-plain error type to the
+// corresponding gae wrapper type. This is intended to be used solely by
+// implementations (not user code). A correct implementation of the gae wrapper
+// should never return an SDK-specific error type if an alternate type appears
+// in this file.
+func FixError(err error) error {
+ if err != nil {
+ // we know that err already conforms to the error interface (or the caller's
+ // method wouldn't compile), so check to see if the error's underlying type
+ // looks like one of the special error types we implement.
+ v := reflect.ValueOf(err)
+ if v.Type().ConvertibleTo(multiErrorType) {
+ err = v.Convert(multiErrorType).Interface().(error)
+ }
+ }
+ return err
+}

Powered by Google App Engine
This is Rietveld 408576698