error.go
  1  // Copyright (c) 2015-2016 The btcsuite developers
  2  // Use of this source code is governed by an ISC
  3  // license that can be found in the LICENSE file.
  4  
  5  package database
  6  
  7  import "fmt"
  8  
  9  // ErrorCode identifies a kind of error.
 10  type ErrorCode int
 11  
 12  // These constants are used to identify a specific database Error.
 13  const (
 14  	// **************************************
 15  	// Errors related to driver registration.
 16  	// **************************************
 17  
 18  	// ErrDbTypeRegistered indicates two different database drivers
 19  	// attempt to register with the name database type.
 20  	ErrDbTypeRegistered ErrorCode = iota
 21  
 22  	// *************************************
 23  	// Errors related to database functions.
 24  	// *************************************
 25  
 26  	// ErrDbUnknownType indicates there is no driver registered for
 27  	// the specified database type.
 28  	ErrDbUnknownType
 29  
 30  	// ErrDbDoesNotExist indicates open is called for a database that
 31  	// does not exist.
 32  	ErrDbDoesNotExist
 33  
 34  	// ErrDbExists indicates create is called for a database that
 35  	// already exists.
 36  	ErrDbExists
 37  
 38  	// ErrDbNotOpen indicates a database instance is accessed before
 39  	// it is opened or after it is closed.
 40  	ErrDbNotOpen
 41  
 42  	// ErrDbAlreadyOpen indicates open was called on a database that
 43  	// is already open.
 44  	ErrDbAlreadyOpen
 45  
 46  	// ErrInvalid indicates the specified database is not valid.
 47  	ErrInvalid
 48  
 49  	// ErrCorruption indicates a checksum failure occurred which invariably
 50  	// means the database is corrupt.
 51  	ErrCorruption
 52  
 53  	// ****************************************
 54  	// Errors related to database transactions.
 55  	// ****************************************
 56  
 57  	// ErrTxClosed indicates an attempt was made to commit or rollback a
 58  	// transaction that has already had one of those operations performed.
 59  	ErrTxClosed
 60  
 61  	// ErrTxNotWritable indicates an operation that requires write access to
 62  	// the database was attempted against a read-only transaction.
 63  	ErrTxNotWritable
 64  
 65  	// **************************************
 66  	// Errors related to metadata operations.
 67  	// **************************************
 68  
 69  	// ErrBucketNotFound indicates an attempt to access a bucket that has
 70  	// not been created yet.
 71  	ErrBucketNotFound
 72  
 73  	// ErrBucketExists indicates an attempt to create a bucket that already
 74  	// exists.
 75  	ErrBucketExists
 76  
 77  	// ErrBucketNameRequired indicates an attempt to create a bucket with a
 78  	// blank name.
 79  	ErrBucketNameRequired
 80  
 81  	// ErrKeyRequired indicates at attempt to insert a zero-length key.
 82  	ErrKeyRequired
 83  
 84  	// ErrKeyTooLarge indicates an attmempt to insert a key that is larger
 85  	// than the max allowed key size.  The max key size depends on the
 86  	// specific backend driver being used.  As a general rule, key sizes
 87  	// should be relatively, so this should rarely be an issue.
 88  	ErrKeyTooLarge
 89  
 90  	// ErrValueTooLarge indicates an attmpt to insert a value that is larger
 91  	// than max allowed value size.  The max key size depends on the
 92  	// specific backend driver being used.
 93  	ErrValueTooLarge
 94  
 95  	// ErrIncompatibleValue indicates the value in question is invalid for
 96  	// the specific requested operation.  For example, trying create or
 97  	// delete a bucket with an existing non-bucket key, attempting to create
 98  	// or delete a non-bucket key with an existing bucket key, or trying to
 99  	// delete a value via a cursor when it points to a nested bucket.
100  	ErrIncompatibleValue
101  
102  	// ***************************************
103  	// Errors related to block I/O operations.
104  	// ***************************************
105  
106  	// ErrBlockNotFound indicates a block with the provided hash does not
107  	// exist in the database.
108  	ErrBlockNotFound
109  
110  	// ErrBlockExists indicates a block with the provided hash already
111  	// exists in the database.
112  	ErrBlockExists
113  
114  	// ErrBlockRegionInvalid indicates a region that exceeds the bounds of
115  	// the specified block was requested.  When the hash provided by the
116  	// region does not correspond to an existing block, the error will be
117  	// ErrBlockNotFound instead.
118  	ErrBlockRegionInvalid
119  
120  	// ***********************************
121  	// Support for driver-specific errors.
122  	// ***********************************
123  
124  	// ErrDriverSpecific indicates the Err field is a driver-specific error.
125  	// This provides a mechanism for drivers to plug-in their own custom
126  	// errors for any situations which aren't already covered by the error
127  	// codes provided by this package.
128  	ErrDriverSpecific
129  
130  	// numErrorCodes is the maximum error code number used in tests.
131  	numErrorCodes
132  )
133  
134  // Map of ErrorCode values back to their constant names for pretty printing.
135  var errorCodeStrings = map[ErrorCode]string{
136  	ErrDbTypeRegistered:   "ErrDbTypeRegistered",
137  	ErrDbUnknownType:      "ErrDbUnknownType",
138  	ErrDbDoesNotExist:     "ErrDbDoesNotExist",
139  	ErrDbExists:           "ErrDbExists",
140  	ErrDbNotOpen:          "ErrDbNotOpen",
141  	ErrDbAlreadyOpen:      "ErrDbAlreadyOpen",
142  	ErrInvalid:            "ErrInvalid",
143  	ErrCorruption:         "ErrCorruption",
144  	ErrTxClosed:           "ErrTxClosed",
145  	ErrTxNotWritable:      "ErrTxNotWritable",
146  	ErrBucketNotFound:     "ErrBucketNotFound",
147  	ErrBucketExists:       "ErrBucketExists",
148  	ErrBucketNameRequired: "ErrBucketNameRequired",
149  	ErrKeyRequired:        "ErrKeyRequired",
150  	ErrKeyTooLarge:        "ErrKeyTooLarge",
151  	ErrValueTooLarge:      "ErrValueTooLarge",
152  	ErrIncompatibleValue:  "ErrIncompatibleValue",
153  	ErrBlockNotFound:      "ErrBlockNotFound",
154  	ErrBlockExists:        "ErrBlockExists",
155  	ErrBlockRegionInvalid: "ErrBlockRegionInvalid",
156  	ErrDriverSpecific:     "ErrDriverSpecific",
157  }
158  
159  // String returns the ErrorCode as a human-readable name.
160  func (e ErrorCode) String() string {
161  	if s := errorCodeStrings[e]; s != "" {
162  		return s
163  	}
164  	return fmt.Sprintf("Unknown ErrorCode (%d)", int(e))
165  }
166  
167  // Error provides a single type for errors that can happen during database
168  // operation.  It is used to indicate several types of failures including errors
169  // with caller requests such as specifying invalid block regions or attempting
170  // to access data against closed database transactions, driver errors, errors
171  // retrieving data, and errors communicating with database servers.
172  //
173  // The caller can use type assertions to determine if an error is an Error and
174  // access the ErrorCode field to ascertain the specific reason for the failure.
175  //
176  // The ErrDriverSpecific error code will also have the Err field set with the
177  // underlying error.  Depending on the backend driver, the Err field might be
178  // set to the underlying error for other error codes as well.
179  type Error struct {
180  	ErrorCode   ErrorCode // Describes the kind of error
181  	Description string    // Human readable description of the issue
182  	Err         error     // Underlying error
183  }
184  
185  // Error satisfies the error interface and prints human-readable errors.
186  func (e Error) Error() string {
187  	if e.Err != nil {
188  		return e.Description + ": " + e.Err.Error()
189  	}
190  	return e.Description
191  }
192  
193  // makeError creates an Error given a set of arguments.  The error code must
194  // be one of the error codes provided by this package.
195  func makeError(c ErrorCode, desc string, err error) Error {
196  	return Error{ErrorCode: c, Description: desc, Err: err}
197  }