// Copyright (c) 2021 Gitpod GmbH. All rights reserved. // Licensed under the GNU Affero General Public License (AGPL). // See License-AGPL.txt in the project root for license information. package pkg import ( "net/http" "time" "github.com/gitpod-io/gitpod/common-go/log" "github.com/sirupsen/logrus" ) func (o *OpenVSXProxy) ErrorHandler(rw http.ResponseWriter, r *http.Request, e error) { reqid := r.Context().Value(REQUEST_ID_CTX).(string) key, ok := r.Context().Value(REQUEST_CACHE_KEY_CTX).(string) logFields := logrus.Fields{ LOG_FIELD_FUNC: "error_handler", LOG_FIELD_REQUEST_ID: reqid, LOG_FIELD_REQUEST: key, LOG_FIELD_STATUS: "error", } start := time.Now() defer func(ts time.Time) { duration := time.Since(ts) o.metrics.DurationResponseProcessingHistogram.Observe(duration.Seconds()) log. WithFields(logFields). WithFields(o.DurationLogFields(duration)). Info("processing error finished") }(start) log.WithFields(logFields).WithError(e).Warn("handling error") o.metrics.IncStatusCounter(r, "error") if !ok { return } if key == "" { log.WithFields(logFields).Error("cache key header is missing") rw.WriteHeader(http.StatusBadGateway) return } cached, ok, err := o.ReadCache(key) if err != nil { log.WithFields(logFields).WithError(err).Error("cannot read from cache") rw.WriteHeader(http.StatusBadGateway) return } if !ok { log.WithFields(logFields).Debug("cache has no entry for key") rw.WriteHeader(http.StatusBadGateway) return } for k, v := range cached.Header { for i, val := range v { if i == 0 { rw.Header().Set(k, val) } else { rw.Header().Add(k, val) } } } if v := rw.Header().Get("Access-Control-Allow-Origin"); v != "" && v != "*" { rw.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) } rw.WriteHeader(cached.StatusCode) rw.Write(cached.Body) log.WithFields(logFields).Debug("used cached response due to a proxy error") o.metrics.BackupCacheServeCounter.Inc() }