Skip to content

Commit

Permalink
Minimize log messages (#467)
Browse files Browse the repository at this point in the history
* Updated some adapters to use new error types.

* Made adform, adtelligent, and facebook return the right error types.

* Updated conversant to use the new error types.

* Updated eplanning to use the new error types.

* Updated index to use the new error types.

* Updated lifestreet to use the new error types.

* Updated openx to use the new error types.

* Updated pubmatic to use the new error types.

* Updated pulsepoint to use the new error types. Fixed some compiler errors in pubmatic

* Updated the utils function.

* Updated the sovrn adapter.

* Updated the rubicon errors.

* Made the appnexus adapter conform to the same pattern as the others.

* Cleaned up a thing in pubmatic. Made logging more sparse in the auction() code.
  • Loading branch information
dbemiller committed Apr 19, 2018
1 parent a4629ea commit 94684c2
Show file tree
Hide file tree
Showing 18 changed files with 435 additions and 122 deletions.
52 changes: 42 additions & 10 deletions adapters/adform/adform.go
Expand Up @@ -105,8 +105,16 @@ func (a *AdformAdapter) Call(ctx context.Context, request *pbs.PBSRequest, bidde
}
responseBody := string(body)

if response.StatusCode == http.StatusBadRequest {
return nil, adapters.BadInputError{
Message: fmt.Sprintf("HTTP status %d; body: %s", response.StatusCode, responseBody),
}
}

if response.StatusCode != 200 {
return nil, fmt.Errorf("HTTP status %d; body: %s", response.StatusCode, responseBody)
return nil, adapters.BadServerResponseError{
Message: fmt.Sprintf("HTTP status %d; body: %s", response.StatusCode, responseBody),
}
}

if request.IsDebug {
Expand All @@ -132,10 +140,14 @@ func pbsRequestToAdformRequest(a *AdformAdapter, request *pbs.PBSRequest, bidder
}
mid, err := adformAdUnit.MasterTagId.Int64()
if err != nil {
return nil, err
return nil, &adapters.BadInputError{
Message: err.Error(),
}
}
if mid <= 0 {
return nil, fmt.Errorf("master tag(placement) id is invalid=%s", adformAdUnit.MasterTagId)
return nil, &adapters.BadInputError{
Message: fmt.Sprintf("master tag(placement) id is invalid=%s", adformAdUnit.MasterTagId),
}
}
adformAdUnit.bidId = adUnit.BidID
adformAdUnit.adUnitCode = adUnit.Code
Expand Down Expand Up @@ -222,7 +234,9 @@ func (r *adformRequest) buildAdformHeaders(a *AdformAdapter) http.Header {
func parseAdformBids(response []byte) ([]*adformBid, error) {
var bids []*adformBid
if err := json.Unmarshal(response, &bids); err != nil {
return nil, err
return nil, &adapters.BadServerResponseError{
Message: err.Error(),
}
}

return bids, nil
Expand Down Expand Up @@ -264,28 +278,38 @@ func openRtbToAdformRequest(request *openrtb.BidRequest) (*adformRequest, []erro
secure := false
for _, imp := range request.Imp {
if imp.Banner == nil {
errors = append(errors, fmt.Errorf("Adform adapter supports only banner Imps for now. Ignoring Imp ID=%s", imp.ID))
errors = append(errors, &adapters.BadInputError{
Message: fmt.Sprintf("Adform adapter supports only banner Imps for now. Ignoring Imp ID=%s", imp.ID),
})
continue
}

params, _, _, err := jsonparser.Get(imp.Ext, "bidder")
if err != nil {
errors = append(errors, err)
errors = append(errors, &adapters.BadInputError{
Message: err.Error(),
})
continue
}
var adformAdUnit adformAdUnit
if err := json.Unmarshal(params, &adformAdUnit); err != nil {
errors = append(errors, err)
errors = append(errors, &adapters.BadInputError{
Message: err.Error(),
})
continue
}

mid, err := adformAdUnit.MasterTagId.Int64()
if err != nil {
errors = append(errors, err)
errors = append(errors, &adapters.BadInputError{
Message: err.Error(),
})
continue
}
if mid <= 0 {
errors = append(errors, fmt.Errorf("master tag(placement) id is invalid=%s", adformAdUnit.MasterTagId))
errors = append(errors, &adapters.BadInputError{
Message: fmt.Sprintf("master tag(placement) id is invalid=%s", adformAdUnit.MasterTagId),
})
continue
}

Expand Down Expand Up @@ -325,8 +349,16 @@ func (a *AdformAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRe
return nil, nil
}

if response.StatusCode == http.StatusBadRequest {
return nil, []error{&adapters.BadInputError{
Message: fmt.Sprintf("unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
}}
}

if response.StatusCode != http.StatusOK {
return nil, []error{fmt.Errorf("unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode)}
return nil, []error{&adapters.BadServerResponseError{
Message: fmt.Sprintf("unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
}}
}

adformOutput, err := parseAdformBids(response.Body)
Expand Down
24 changes: 18 additions & 6 deletions adapters/adtelligent/adtelligent.go
Expand Up @@ -93,7 +93,9 @@ func (a *AdtelligentAdapter) MakeBids(bidReq *openrtb.BidRequest, unused *adapte

var bidResp openrtb.BidResponse
if err := json.Unmarshal(httpRes.Body, &bidResp); err != nil {
return nil, []error{fmt.Errorf("error while decoding response, err: %s", err)}
return nil, []error{&adapters.BadServerResponseError{
Message: fmt.Sprintf("error while decoding response, err: %s", err),
}}
}

var bids []*adapters.TypedBid
Expand Down Expand Up @@ -121,7 +123,9 @@ func (a *AdtelligentAdapter) MakeBids(bidReq *openrtb.BidRequest, unused *adapte
}

if !impOK {
errors = append(errors, fmt.Errorf("ignoring bid id=%s, request doesn't contain any impression with id=%s", bid.ID, bid.ImpID))
errors = append(errors, &adapters.BadServerResponseError{
Message: fmt.Sprintf("ignoring bid id=%s, request doesn't contain any impression with id=%s", bid.ID, bid.ImpID),
})
continue
}

Expand All @@ -138,23 +142,31 @@ func (a *AdtelligentAdapter) MakeBids(bidReq *openrtb.BidRequest, unused *adapte
func validateImpression(imp *openrtb.Imp) (int, error) {

if imp.Banner == nil && imp.Video == nil {
return 0, fmt.Errorf("ignoring imp id=%s, Adtelligent supports only Video and Banner", imp.ID)
return 0, &adapters.BadInputError{
Message: fmt.Sprintf("ignoring imp id=%s, Adtelligent supports only Video and Banner", imp.ID),
}
}

if 0 == len(imp.Ext) {
return 0, fmt.Errorf("ignoring imp id=%s, extImpBidder is empty", imp.ID)
return 0, &adapters.BadInputError{
Message: fmt.Sprintf("ignoring imp id=%s, extImpBidder is empty", imp.ID),
}
}

var bidderExt adapters.ExtImpBidder

if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
return 0, fmt.Errorf("ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err)
return 0, &adapters.BadInputError{
Message: fmt.Sprintf("ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err),
}
}

impExt := openrtb_ext.ExtImpAdtelligent{}
err := json.Unmarshal(bidderExt.Bidder, &impExt)
if err != nil {
return 0, fmt.Errorf("ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err)
return 0, &adapters.BadInputError{
Message: fmt.Sprintf("ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err),
}
}

// common extension for all impressions
Expand Down
35 changes: 28 additions & 7 deletions adapters/appnexus/appnexus.go
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
Expand Down Expand Up @@ -100,7 +99,9 @@ func (a *AppNexusAdapter) Call(ctx context.Context, req *pbs.PBSRequest, bidder
}

if params.PlacementId == 0 && (params.InvCode == "" || params.Member == "") {
return nil, errors.New("No placement or member+invcode provided")
return nil, adapters.BadInputError{
Message: "No placement or member+invcode provided",
}
}

// Fixes some segfaults. Since this is legacy code, I'm not looking into it too deeply
Expand Down Expand Up @@ -186,8 +187,16 @@ func (a *AppNexusAdapter) Call(ctx context.Context, req *pbs.PBSRequest, bidder
}
responseBody := string(body)

if anResp.StatusCode != 200 {
return nil, fmt.Errorf("HTTP status %d; body: %s", anResp.StatusCode, responseBody)
if anResp.StatusCode == http.StatusBadRequest {
return nil, adapters.BadInputError{
Message: fmt.Sprintf("HTTP status %d; body: %s", anResp.StatusCode, responseBody),
}
}

if anResp.StatusCode != http.StatusOK {
return nil, adapters.BadServerResponseError{
Message: fmt.Sprintf("HTTP status %d; body: %s", anResp.StatusCode, responseBody),
}
}

if req.IsDebug {
Expand All @@ -206,7 +215,9 @@ func (a *AppNexusAdapter) Call(ctx context.Context, req *pbs.PBSRequest, bidder
for _, bid := range sb.Bid {
bidID := bidder.LookupBidID(bid.ImpID)
if bidID == "" {
return nil, fmt.Errorf("Unknown ad unit code '%s'", bid.ImpID)
return nil, adapters.BadServerResponseError{
Message: fmt.Sprintf("Unknown ad unit code '%s'", bid.ImpID),
}
}

pbid := pbs.PBSBid{
Expand Down Expand Up @@ -301,7 +312,9 @@ func keys(m map[string]bool) []string {
func preprocess(imp *openrtb.Imp) (string, error) {
// We don't support audio imps yet.
if imp.Audio != nil {
return "", fmt.Errorf("Appnexus doesn't support audio Imps. Ignoring Imp ID=%s", imp.ID)
return "", adapters.BadInputError{
Message: fmt.Sprintf("Appnexus doesn't support audio Imps. Ignoring Imp ID=%s", imp.ID),
}
}
var bidderExt adapters.ExtImpBidder
if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
Expand All @@ -326,7 +339,9 @@ func preprocess(imp *openrtb.Imp) (string, error) {
}

if appnexusExt.PlacementId == 0 && (appnexusExt.InvCode == "" || appnexusExt.Member == "") {
return "", errors.New("No placement or member+invcode provided")
return "", adapters.BadInputError{
Message: "No placement or member+invcode provided",
}
}

if appnexusExt.InvCode != "" {
Expand Down Expand Up @@ -387,6 +402,12 @@ func (a *AppNexusAdapter) MakeBids(internalRequest *openrtb.BidRequest, external
return nil, nil
}

if response.StatusCode == http.StatusBadRequest {
return nil, []error{adapters.BadInputError{
Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
}}
}

if response.StatusCode != http.StatusOK {
return nil, []error{fmt.Errorf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode)}
}
Expand Down
36 changes: 29 additions & 7 deletions adapters/audienceNetwork/facebook.go
Expand Up @@ -81,14 +81,26 @@ func (a *FacebookAdapter) callOne(ctx context.Context, reqJSON bytes.Buffer) (re
body, _ := ioutil.ReadAll(anResp.Body)
result.ResponseBody = string(body)

if anResp.StatusCode != 200 {
err = fmt.Errorf("HTTP status %d; body: %s", anResp.StatusCode, result.ResponseBody)
if anResp.StatusCode == http.StatusBadRequest {
err = &adapters.BadInputError{
Message: fmt.Sprintf("HTTP status %d; body: %s", anResp.StatusCode, result.ResponseBody),
}
return
}

if anResp.StatusCode != http.StatusOK {
err = &adapters.BadServerResponseError{
Message: fmt.Sprintf("HTTP status %d; body: %s", anResp.StatusCode, result.ResponseBody),
}
return
}

var bidResp openrtb.BidResponse
err = json.Unmarshal(body, &bidResp)
if err != nil {
err = &adapters.BadServerResponseError{
Message: err.Error(),
}
return
}
if len(bidResp.SeatBid) == 0 {
Expand Down Expand Up @@ -142,7 +154,9 @@ func (a *FacebookAdapter) MakeOpenRtbBidRequest(req *pbs.PBSRequest, bidder *pbs
// if instl = 0 and type is banner, do not send non supported size
if fbReq.Imp[0].Instl == 0 && fbReq.Imp[0].Banner != nil {
if !supportedHeight[*fbReq.Imp[0].Banner.H] {
return fbReq, errors.New("Facebook do not support banner height other than 50, 90 and 250")
return fbReq, &adapters.BadInputError{
Message: "Facebook do not support banner height other than 50, 90 and 250",
}
}
// do not send legacy 320x50 size to facebook, instead use 0x50
if *fbReq.Imp[0].Banner.W == 320 && *fbReq.Imp[0].Banner.H == 50 {
Expand All @@ -151,7 +165,9 @@ func (a *FacebookAdapter) MakeOpenRtbBidRequest(req *pbs.PBSRequest, bidder *pbs
}
return fbReq, nil
} else {
return fbReq, errors.New("No supported impressions")
return fbReq, &adapters.BadInputError{
Message: "No supported impressions",
}
}
}

Expand All @@ -165,11 +181,15 @@ func (a *FacebookAdapter) GenerateRequestsForFacebook(req *pbs.PBSRequest, bidde
return nil, err
}
if params.PlacementId == "" {
return nil, errors.New("Missing placementId param")
return nil, &adapters.BadInputError{
Message: "Missing placementId param",
}
}
s := strings.Split(params.PlacementId, "_")
if len(s) != 2 {
return nil, fmt.Errorf("Invalid placementId param '%s'", params.PlacementId)
return nil, &adapters.BadInputError{
Message: fmt.Sprintf("Invalid placementId param '%s'", params.PlacementId),
}
}
pubId := s[0]

Expand Down Expand Up @@ -222,7 +242,9 @@ func (a *FacebookAdapter) Call(ctx context.Context, req *pbs.PBSRequest, bidder
}
result.Bid.BidID = bidder.LookupBidID(result.Bid.AdUnitCode)
if result.Bid.BidID == "" {
result.Error = fmt.Errorf("Unknown ad unit code '%s'", result.Bid.AdUnitCode)
result.Error = &adapters.BadServerResponseError{
Message: fmt.Sprintf("Unknown ad unit code '%s'", result.Bid.AdUnitCode),
}
result.Bid = nil
}
}
Expand Down
34 changes: 34 additions & 0 deletions adapters/bidder.go
Expand Up @@ -16,6 +16,8 @@ type Bidder interface {
//
// The errors should contain a list of errors which explain why this bidder's bids will be
// "subpar" in some way. For example: the request contained ad types which this bidder doesn't support.
//
// If the error is caused by bad user input, return a BadInputError.
MakeRequests(request *openrtb.BidRequest) ([]*RequestData, []error)

// MakeBids unpacks the server's response into Bids.
Expand All @@ -24,9 +26,41 @@ type Bidder interface {
//
// The errors should contain a list of errors which explain why this bidder's bids will be
// "subpar" in some way. For example: the server response didn't have the expected format.
//
// If the error was caused by bad user input, return a BadInputError.
// If the error was caused by a bad server response, return a BadServerResponseError
MakeBids(internalRequest *openrtb.BidRequest, externalRequest *RequestData, response *ResponseData) ([]*TypedBid, []error)
}

// BadInputError should be used when returning errors which are caused by bad input.
// It should _not_ be used if the error is a server-side issue (e.g. failed to send the external request).
//
// BadInputErrors will not be written to the app log, since it's not an actionable item for the Prebid Server hosts.
type BadInputError struct {
Message string
}

func (err BadInputError) Error() string {
return err.Message
}

// BadServerResponseError should be used when returning errors which are caused by bad/unexpected behavior on the remote server.
//
// For example:
//
// - The external server responded with a 500
// - The external server gave a malformed or unexpected response.
//
// These should not be used to log _connection_ errors (e.g. "couldn't find host"),
// which may indicate config issues for the PBS host company
type BadServerResponseError struct {
Message string
}

func (err BadServerResponseError) Error() string {
return err.Message
}

// TypedBid packages the openrtb.Bid with any bidder-specific information that PBS needs to populate an
// openrtb_ext.ExtBidPrebid.
//
Expand Down

0 comments on commit 94684c2

Please sign in to comment.