Beispiel #1
0
func Pf(w io.Writer, r *http.Request, f string, vs ...interface{}) {

	for idx, v := range vs {
		switch v := v.(type) {
		case []byte:
			if len(v) > 1024*5 {
				appdx := append([]byte(" ...omitted... "), v[len(v)-100:]...)
				vs[idx] = append(v[:1024*5], appdx...)
			}
		case string:
			if len(v) > 1024*5 {
				appdx := " ...omitted... " + v[len(v)-100:]
				vs[idx] = v[:1024*5] + appdx
			}
		}
	}

	// Prepare the string
	var s string
	if len(vs) > 0 {
		s = fmt.Sprintf(f, vs...)
	} else {
		s = f
	}

	if s == "" {
		return
	}

	// Write it to http response or bytes.Buffer
	// unless prefixed with 'lo ' - log only.
	// Thread-safety could be introduced by syncing/locking w.
	if w != nil && !strings.HasPrefix(s, "lo ") {
		w.Write([]byte(s))
		w.Write([]byte{'\n'})
	}

	// Write to log/gae-log
	// Adding src code info

	line, file := runtimepb.LineFileXUp(1)
	// if strings.HasSuffix(file, "log.go")
	if strings.HasSuffix(file, runtimepb.ThisFile()) { // change
		line, file = runtimepb.LineFileXUp(2)
	}

	if len(s) < 60 {
		s = stringspb.ToLen(s, 60)
	}
	s = fmt.Sprintf("%v - %v:%v", s, file, line)

	// Log it
	c, _ := util_appengine.SafelyExtractGaeCtxError(r)
	if c == nil {
		lnp.Printf(s)
	} else {
		aelog.Infof(c, s)
	}

}
Beispiel #2
0
/*

 A generic error function

 Utility functions pass   errors up to the caller


 Higher level "request functions" handle errors directly
    often we want to abort further request processing
 	and issue an message into the http response AND into the logs

 Sometimes we only want to write the error into the logs and
    continue operation => continueExecution true

  In addition to the generic error messages
  we may add specific error explanations or values
  via parameter vs - for display and logging
  We also show the source file+location.

  A "global panic catcher" in util_err.Adapter() ...defer(){}
  cooperates - suppressing the stacktrace and
  healing the panic

*/
func E(w http.ResponseWriter, r *http.Request,
	bool_or_err interface{},
	continueExecution bool,
	vs ...interface{}) {

	var err error

	switch bool_or_err.(type) {
	default:
		type_unknown := fmt.Sprintf("%T", bool_or_err)
		err = errors.New("only bool or error - instead: -" + type_unknown + "-")
		panic(err)
	case nil:
		return
	case bool:
		if bool_or_err.(bool) {
			return
		}
		err = errors.New("Not OK (type conv?)")
	case error:
		err = bool_or_err.(error)
	}

	if err != nil {
		line, file := runtimepb.LineFileXUp(1)
		// we cannot determine, whether html is already sent
		// we cannot determine, whether we are in plaintext or html context
		// thus we need the <br>
		s := fmt.Sprintf("ERR: %v  <br>\n\t /%s:%d \n", err, file, line)
		if len(vs) > 0 {
			s = s + "\t" + fmt.Sprint(vs...) + "\n"
		}

		if continueExecution {
			c, _ := util_appengine.SafelyExtractGaeCtxError(r)
			if c == nil {
				log.Printf(s)
			} else {
				aelog.Infof(c, s)
			}
		} else {
			c, _ := util_appengine.SafelyExtractGaeCtxError(r)
			if c == nil {
				log.Printf(s)
			} else {
				aelog.Errorf(c, s)
			}
			w.Header().Set("Content-Type", "text/plain")
			http.Error(w, s, http.StatusInternalServerError)
			panic("abort_handler_processing")
		}
	}

}