gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

internal.go (3152B)


      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))