3 // Copyright 2017 Microsoft Corporation
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
23 // UndefinedStatusCode is used when HTTP status code is not available for an error.
24 UndefinedStatusCode = 0
27 // DetailedError encloses a error with details of the package, method, and associated HTTP
28 // status code (if any).
29 type DetailedError struct {
32 // PackageType is the package type of the object emitting the error. For types, the value
33 // matches that produced the the '%T' format specifier of the fmt package. For other elements,
34 // such as functions, it is just the package name (e.g., "autorest").
37 // Method is the name of the method raising the error.
40 // StatusCode is the HTTP Response StatusCode (if non-zero) that led to the error.
41 StatusCode interface{}
43 // Message is the error message.
46 // Service Error is the response body of failed API in bytes
49 // Response is the response object that was returned during failure if applicable.
50 Response *http.Response
53 // NewError creates a new Error conforming object from the passed packageType, method, and
54 // message. message is treated as a format string to which the optional args apply.
55 func NewError(packageType string, method string, message string, args ...interface{}) DetailedError {
56 return NewErrorWithError(nil, packageType, method, nil, message, args...)
59 // NewErrorWithResponse creates a new Error conforming object from the passed
60 // packageType, method, statusCode of the given resp (UndefinedStatusCode if
61 // resp is nil), and message. message is treated as a format string to which the
62 // optional args apply.
63 func NewErrorWithResponse(packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError {
64 return NewErrorWithError(nil, packageType, method, resp, message, args...)
67 // NewErrorWithError creates a new Error conforming object from the
68 // passed packageType, method, statusCode of the given resp (UndefinedStatusCode
69 // if resp is nil), message, and original error. message is treated as a format
70 // string to which the optional args apply.
71 func NewErrorWithError(original error, packageType string, method string, resp *http.Response, message string, args ...interface{}) DetailedError {
72 if v, ok := original.(DetailedError); ok {
76 statusCode := UndefinedStatusCode
78 statusCode = resp.StatusCode
83 PackageType: packageType,
85 StatusCode: statusCode,
86 Message: fmt.Sprintf(message, args...),
91 // Error returns a formatted containing all available details (i.e., PackageType, Method,
92 // StatusCode, Message, and original error (if any)).
93 func (e DetailedError) Error() string {
94 if e.Original == nil {
95 return fmt.Sprintf("%s#%s: %s: StatusCode=%d", e.PackageType, e.Method, e.Message, e.StatusCode)
97 return fmt.Sprintf("%s#%s: %s: StatusCode=%d -- Original Error: %v", e.PackageType, e.Method, e.Message, e.StatusCode, e.Original)