Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / google.golang.org / appengine / internal / internal.go
1 // Copyright 2011 Google Inc. All rights reserved.
2 // Use of this source code is governed by the Apache 2.0
3 // license that can be found in the LICENSE file.
4
5 // Package internal provides support for package appengine.
6 //
7 // Programs should not use this package directly. Its API is not stable.
8 // Use packages appengine and appengine/* instead.
9 package internal
10
11 import (
12         "fmt"
13
14         "github.com/golang/protobuf/proto"
15
16         remotepb "google.golang.org/appengine/internal/remote_api"
17 )
18
19 // errorCodeMaps is a map of service name to the error code map for the service.
20 var errorCodeMaps = make(map[string]map[int32]string)
21
22 // RegisterErrorCodeMap is called from API implementations to register their
23 // error code map. This should only be called from init functions.
24 func RegisterErrorCodeMap(service string, m map[int32]string) {
25         errorCodeMaps[service] = m
26 }
27
28 type timeoutCodeKey struct {
29         service string
30         code    int32
31 }
32
33 // timeoutCodes is the set of service+code pairs that represent timeouts.
34 var timeoutCodes = make(map[timeoutCodeKey]bool)
35
36 func RegisterTimeoutErrorCode(service string, code int32) {
37         timeoutCodes[timeoutCodeKey{service, code}] = true
38 }
39
40 // APIError is the type returned by appengine.Context's Call method
41 // when an API call fails in an API-specific way. This may be, for instance,
42 // a taskqueue API call failing with TaskQueueServiceError::UNKNOWN_QUEUE.
43 type APIError struct {
44         Service string
45         Detail  string
46         Code    int32 // API-specific error code
47 }
48
49 func (e *APIError) Error() string {
50         if e.Code == 0 {
51                 if e.Detail == "" {
52                         return "APIError <empty>"
53                 }
54                 return e.Detail
55         }
56         s := fmt.Sprintf("API error %d", e.Code)
57         if m, ok := errorCodeMaps[e.Service]; ok {
58                 s += " (" + e.Service + ": " + m[e.Code] + ")"
59         } else {
60                 // Shouldn't happen, but provide a bit more detail if it does.
61                 s = e.Service + " " + s
62         }
63         if e.Detail != "" {
64                 s += ": " + e.Detail
65         }
66         return s
67 }
68
69 func (e *APIError) IsTimeout() bool {
70         return timeoutCodes[timeoutCodeKey{e.Service, e.Code}]
71 }
72
73 // CallError is the type returned by appengine.Context's Call method when an
74 // API call fails in a generic way, such as RpcError::CAPABILITY_DISABLED.
75 type CallError struct {
76         Detail string
77         Code   int32
78         // TODO: Remove this if we get a distinguishable error code.
79         Timeout bool
80 }
81
82 func (e *CallError) Error() string {
83         var msg string
84         switch remotepb.RpcError_ErrorCode(e.Code) {
85         case remotepb.RpcError_UNKNOWN:
86                 return e.Detail
87         case remotepb.RpcError_OVER_QUOTA:
88                 msg = "Over quota"
89         case remotepb.RpcError_CAPABILITY_DISABLED:
90                 msg = "Capability disabled"
91         case remotepb.RpcError_CANCELLED:
92                 msg = "Canceled"
93         default:
94                 msg = fmt.Sprintf("Call error %d", e.Code)
95         }
96         s := msg + ": " + e.Detail
97         if e.Timeout {
98                 s += " (timeout)"
99         }
100         return s
101 }
102
103 func (e *CallError) IsTimeout() bool {
104         return e.Timeout
105 }
106
107 // NamespaceMods is a map from API service to a function that will mutate an RPC request to attach a namespace.
108 // The function should be prepared to be called on the same message more than once; it should only modify the
109 // RPC request the first time.
110 var NamespaceMods = make(map[string]func(m proto.Message, namespace string))