Beispiel #1
0
// deal makes the response in error cases somewhat nicer. It will try
// to figure out what actually went wrong and inform the user.
// It should not be called if the request went fine. If status is below
// 400, and err is not nil, it will assume an internal server error.
// Generally, if you pass a nil error, don't expect deal to do anything
// useful.
func deal(ctx context.Context, w http.ResponseWriter, r *http.Request, status int, err error) {
	// Getting an error and a status code blow 400 is somewhat paradox.
	// Also, if the status is the zero value, assume that we're dealing
	// with an internal server error.
	if err != nil && status < 400 || status == 0 {
		status = http.StatusInternalServerError
	}

	msg := "Sorry, Coduno encountered an error: " + http.StatusText(status) + "\n\n"
	msg += "If you think this is a bug, please consider filing\n"
	msg += "it at https://github.com/coduno/api/issues\n\n"

	if ctx != nil {
		msg += "Your request ID is " + appengine.RequestID(ctx) + " (important to track down what went wrong)\n\n"
	}

	// If we don't have an error it's really hard to make sense.
	if err == nil {
		w.WriteHeader(status)
		w.Write([]byte(msg))
		return
	}

	if t, ok := err.(trace); ok {
		msg += "Trace:\n"
		msg += strings.Replace(string(t.t), "\n", "\n\t", -1)
		msg += "\n"
		err = t.e
	}

	if appengine.IsOverQuota(err) {
		msg += "Reason: Over Quota"
	} else if appengine.IsTimeoutError(err) {
		msg += "Reason: Timeout Error"
	} else {
		msg += fmt.Sprintf("Reason: %s", err)
	}

	w.WriteHeader(status)
	w.Write([]byte(msg))
}
Beispiel #2
0
func (g giImpl) IsOverQuota(err error) bool {
	return appengine.IsOverQuota(err)
}