go.uber.org/yarpc@v1.72.1/transport/http/codes.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package http 22 23 import "go.uber.org/yarpc/yarpcerrors" 24 25 var ( 26 // _codeToStatusCode maps all Codes to their corresponding HTTP status code. 27 _codeToStatusCode = map[yarpcerrors.Code]int{ 28 yarpcerrors.CodeOK: 200, 29 yarpcerrors.CodeCancelled: 499, 30 yarpcerrors.CodeUnknown: 500, 31 yarpcerrors.CodeInvalidArgument: 400, 32 yarpcerrors.CodeDeadlineExceeded: 504, 33 yarpcerrors.CodeNotFound: 404, 34 yarpcerrors.CodeAlreadyExists: 409, 35 yarpcerrors.CodePermissionDenied: 403, 36 yarpcerrors.CodeResourceExhausted: 429, 37 yarpcerrors.CodeFailedPrecondition: 400, 38 yarpcerrors.CodeAborted: 409, 39 yarpcerrors.CodeOutOfRange: 400, 40 yarpcerrors.CodeUnimplemented: 501, 41 yarpcerrors.CodeInternal: 500, 42 yarpcerrors.CodeUnavailable: 503, 43 yarpcerrors.CodeDataLoss: 500, 44 yarpcerrors.CodeUnauthenticated: 401, 45 } 46 47 // _statusCodeToCodes maps HTTP status codes to a slice of their corresponding Codes. 48 _statusCodeToCodes = map[int][]yarpcerrors.Code{ 49 200: {yarpcerrors.CodeOK}, 50 304: {yarpcerrors.CodeOK}, 51 400: { 52 yarpcerrors.CodeInvalidArgument, 53 yarpcerrors.CodeFailedPrecondition, 54 yarpcerrors.CodeOutOfRange, 55 }, 56 401: {yarpcerrors.CodeUnauthenticated}, 57 403: {yarpcerrors.CodePermissionDenied}, 58 404: {yarpcerrors.CodeNotFound}, 59 409: { 60 yarpcerrors.CodeAborted, 61 yarpcerrors.CodeAlreadyExists, 62 }, 63 422: {yarpcerrors.CodeInvalidArgument}, 64 429: {yarpcerrors.CodeResourceExhausted}, 65 499: {yarpcerrors.CodeCancelled}, 66 500: { 67 yarpcerrors.CodeUnknown, 68 yarpcerrors.CodeInternal, 69 yarpcerrors.CodeDataLoss, 70 }, 71 501: {yarpcerrors.CodeUnimplemented}, 72 503: {yarpcerrors.CodeUnavailable}, 73 504: {yarpcerrors.CodeDeadlineExceeded}, 74 } 75 ) 76 77 // statusCodeToBestCode does a best-effort conversion from the given HTTP status 78 // code to a Code. 79 // 80 // If one Code maps to the given HTTP status code, that Code is returned. 81 // If more than one Code maps to the given HTTP status Code, one Code is returned. 82 // If the Code is >=300 and < 400, yarpcerrors.CodeInvalidArgument is returned. 83 // If the Code is >=400 and < 500, yarpcerrors.CodeInvalidArgument is returned. 84 // Else, yarpcerrors.CodeUnknown is returned. 85 func statusCodeToBestCode(statusCode int) yarpcerrors.Code { 86 codes, ok := _statusCodeToCodes[statusCode] 87 if !ok || len(codes) == 0 { 88 // The class of 3XX status code indicates the client must take additional action to complete the request. 89 // In this sense, it is client's fault to have requested the resources in the first place. 90 if statusCode >= 300 && statusCode < 400 { 91 return yarpcerrors.CodeInvalidArgument 92 } 93 if statusCode >= 400 && statusCode < 500 { 94 return yarpcerrors.CodeInvalidArgument 95 } 96 return yarpcerrors.CodeUnknown 97 } 98 return codes[0] 99 }