github.com/davecgh/go-xdr@v0.0.0-20161123171359-e6a2ba005892/xdr/error.go (about) 1 /* 2 * Copyright (c) 2012 Dave Collins <dave@davec.name> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 package xdr 18 19 import ( 20 "fmt" 21 ) 22 23 // ErrorCode identifies a kind of error. 24 type ErrorCode int 25 26 const ( 27 // ErrBadArguments indicates arguments passed to the function are not 28 // what was expected. 29 ErrBadArguments ErrorCode = iota 30 31 // ErrUnsupportedType indicates the Go type is not a supported type for 32 // marshalling and unmarshalling XDR data. 33 ErrUnsupportedType 34 35 // ErrUnexpectedEnd indicates the end of a sequence of bytes was encountered 36 // before it was expected. This typically indicates issues such as 37 // truncated data or improper structure. 38 ErrUnexpectedEnd 39 40 // ErrBadEnumValue indicates an enumeration value is not in the list of 41 // valid values. 42 ErrBadEnumValue 43 44 // ErrNotSettable indicates an interface value cannot be written to. This 45 // usually means the interface value was not passed with the & operator, but 46 // it can also happen if automatic pointer allocation fails. 47 ErrNotSettable 48 49 // ErrOverflow indicates that the data in question is too large to fit into 50 // the corresponding Go or XDR data type. For example, an integer decoded 51 // from XDR that is too large to fit into a target type of int8, or opaque 52 // data that exceeds the max length of a Go slice. 53 ErrOverflow 54 55 // ErrNilInterface indicates an interface with no concrete type information 56 // was encountered. Type information is necessary to perform mapping 57 // between XDR and Go types. 58 ErrNilInterface 59 ) 60 61 // Map of ErrorCode values back to their constant names for pretty printing. 62 var errorCodeStrings = map[ErrorCode]string{ 63 ErrBadArguments: "ErrBadArguments", 64 ErrUnsupportedType: "ErrUnsupportedType", 65 ErrUnexpectedEnd: "ErrUnexpectedEnd", 66 ErrBadEnumValue: "ErrBadEnumValue", 67 ErrNotSettable: "ErrNotSettable", 68 ErrOverflow: "ErrOverflow", 69 ErrNilInterface: "ErrNilInterface", 70 } 71 72 // String returns the ErrorCode as a human-readable name. 73 func (e ErrorCode) String() string { 74 if s := errorCodeStrings[e]; s != "" { 75 return s 76 } 77 return fmt.Sprintf("Unknown ErrorCode (%d)", e) 78 } 79 80 // UnmarshalError describes a problem encountered while unmarshaling data. 81 // Some potential issues are unsupported Go types, attempting to decode a value 82 // which is too large to fit into a specified Go type, and exceeding max slice 83 // limitations. 84 type UnmarshalError struct { 85 ErrorCode ErrorCode // Describes the kind of error 86 Func string // Function name 87 Value interface{} // Value actually parsed where appropriate 88 Description string // Human readable description of the issue 89 } 90 91 // Error satisfies the error interface and prints human-readable errors. 92 func (e *UnmarshalError) Error() string { 93 switch e.ErrorCode { 94 case ErrUnexpectedEnd, ErrBadEnumValue, ErrOverflow: 95 return fmt.Sprintf("xdr:%s: %s - read: '%v'", e.Func, e.Description, e.Value) 96 } 97 return fmt.Sprintf("xdr:%s: %s", e.Func, e.Description) 98 } 99 100 // unmarshalError creates an error given a set of arguments and will copy byte 101 // slices into the Value field since they might otherwise be changed from from 102 // the original value. 103 func unmarshalError(f string, c ErrorCode, desc string, v interface{}) *UnmarshalError { 104 e := &UnmarshalError{ErrorCode: c, Func: f, Description: desc} 105 switch t := v.(type) { 106 case []byte: 107 slice := make([]byte, len(t)) 108 copy(slice, t) 109 e.Value = slice 110 default: 111 e.Value = v 112 } 113 114 return e 115 } 116 117 // MarshalError describes a problem encountered while marshaling data. 118 // Some potential issues are unsupported Go types, attempting to encode more 119 // opaque data than can be represented by a single opaque XDR entry, and 120 // exceeding max slice limitations. 121 type MarshalError struct { 122 ErrorCode ErrorCode // Describes the kind of error 123 Func string // Function name 124 Value interface{} // Value actually parsed where appropriate 125 Description string // Human readable description of the issue 126 } 127 128 // Error satisfies the error interface and prints human-readable errors. 129 func (e *MarshalError) Error() string { 130 switch e.ErrorCode { 131 case ErrUnexpectedEnd, ErrBadEnumValue, ErrOverflow: 132 return fmt.Sprintf("xdr:%s: %s - read: '%v'", e.Func, e.Description, e.Value) 133 } 134 return fmt.Sprintf("xdr:%s: %s", e.Func, e.Description) 135 } 136 137 // marshalError creates an error given a set of arguments and will copy byte 138 // slices into the Value field since they might otherwise be changed from from 139 // the original value. 140 func marshalError(f string, c ErrorCode, desc string, v interface{}) *MarshalError { 141 e := &MarshalError{ErrorCode: c, Func: f, Description: desc} 142 switch t := v.(type) { 143 case []byte: 144 slice := make([]byte, len(t)) 145 copy(slice, t) 146 e.Value = slice 147 default: 148 e.Value = v 149 } 150 151 return e 152 }