Skip to content

Commit

Permalink
error-filter: Propogate body read errors (#158)
Browse files Browse the repository at this point in the history
If we fail to read the entire body, we should propogate that error.

This will allow us to stop emitting this I/O error to Sentry.
  • Loading branch information
EddShaw authored Nov 7, 2022
1 parent 38e4562 commit ac30164
Showing 1 changed file with 34 additions and 17 deletions.
51 changes: 34 additions & 17 deletions errors.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package typhon

import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
"unicode/utf8"

legacyproto "github.com/golang/protobuf/proto"
"github.com/monzo/slog"
Expand Down Expand Up @@ -103,27 +105,42 @@ func ErrorFilter(req Request, svc Service) Response {
}
} else if rsp.StatusCode >= 400 && rsp.StatusCode <= 599 {
// There is an error in the underlying response; unmarshal
b, _ := rsp.BodyBytes(false)
switch rsp.Header.Get("Terror") {
case "1":
var err error
tp := &terrorsproto.Error{}

switch rsp.Header.Get("Content-Type") {
case "application/octet-stream", "application/x-protobuf", "application/protobuf":
err = legacyproto.Unmarshal(b, tp)
default:
err = json.Unmarshal(b, tp)
b, err := rsp.BodyBytes(false)
if err != nil {
var errParams map[string]string
if utf8.Valid(b) {
errParams = map[string]string{
"partially_read_body": string(b),
}
} else {
errParams = map[string]string{
"partially_read_body_base_64": base64.StdEncoding.EncodeToString(b),
}
}
// Don't attempt to parse a partially read error response. Return the underlying read error when this occurs.
rsp.Error = terrors.NewInternalWithCause(err, "reading error response body", errParams, "body_read_error")
} else {
switch rsp.Header.Get("Terror") {
case "1":
var err error
tp := &terrorsproto.Error{}

if err != nil {
slog.Warn(rsp.Request, "Failed to unmarshal terror: %v", err)
switch rsp.Header.Get("Content-Type") {
case "application/octet-stream", "application/x-protobuf", "application/protobuf":
err = legacyproto.Unmarshal(b, tp)
default:
err = json.Unmarshal(b, tp)
}

if err != nil {
slog.Warn(rsp.Request, "Failed to unmarshal terror: %v", err)
rsp.Error = errors.New(string(b))
} else {
rsp.Error = terrors.Unmarshal(tp)
}
default:
rsp.Error = errors.New(string(b))
} else {
rsp.Error = terrors.Unmarshal(tp)
}
default:
rsp.Error = errors.New(string(b))
}
}

Expand Down

0 comments on commit ac30164

Please sign in to comment.