diff --git a/errortypes/errortypes.go b/errortypes/errortypes.go index 6a7f087026b..d51b25436f0 100644 --- a/errortypes/errortypes.go +++ b/errortypes/errortypes.go @@ -7,6 +7,7 @@ const ( TimeoutCode BadInputCode BadServerResponseCode + FailedToRequestBidsCode ) // We should use this code for any Error interface that is not in this package @@ -70,6 +71,23 @@ func (err *BadServerResponse) Code() int { return BadServerResponseCode } +// FailedToRequestBids is an error to cover the case where an adapter failed to generate any http requests to get bids, +// but did not generate any error messages. This should not happen in practice and will signal that an adapter is poorly +// coded. If there was something wrong with a request such that an adapter could not generate a bid, then it should +// generate an error explaining the deficiency. Otherwise it will be extremely difficult to debug the reason why an +// adapter is not bidding. +type FailedToRequestBids struct { + Message string +} + +func (err *FailedToRequestBids) Error() string { + return err.Message +} + +func (err *FailedToRequestBids) Code() int { + return FailedToRequestBidsCode +} + // DecodeError provides the error code for an error, as defined above func DecodeError(err error) int { if ce, ok := err.(Coder); ok { diff --git a/exchange/bidder.go b/exchange/bidder.go index 332973a9a00..b99c8bf4a81 100644 --- a/exchange/bidder.go +++ b/exchange/bidder.go @@ -85,6 +85,10 @@ func (bidder *bidderAdapter) requestBid(ctx context.Context, request *openrtb.Bi reqData, errs := bidder.Bidder.MakeRequests(request) if len(reqData) == 0 { + // If the adapter failed to generate both requests and errors, this is an error. + if len(errs) == 0 { + errs = append(errs, &errortypes.FailedToRequestBids{Message: "The adapter failed to generate any bid requests, but also failed to generate an error explaining why"}) + } return nil, errs } diff --git a/exchange/exchange.go b/exchange/exchange.go index 570a8ffe942..1fe805b8f3c 100644 --- a/exchange/exchange.go +++ b/exchange/exchange.go @@ -239,6 +239,8 @@ func errorsToMetric(errs []error) map[pbsmetrics.AdapterError]struct{} { ret[pbsmetrics.AdapterErrorBadInput] = s case errortypes.BadServerResponseCode: ret[pbsmetrics.AdapterErrorBadServerResponse] = s + case errortypes.FailedToRequestBidsCode: + ret[pbsmetrics.AdapterErrorFailedToRequestBids] = s default: ret[pbsmetrics.AdapterErrorUnknown] = s } diff --git a/pbsmetrics/metrics.go b/pbsmetrics/metrics.go index 2c1e1318975..e901ab2deff 100644 --- a/pbsmetrics/metrics.go +++ b/pbsmetrics/metrics.go @@ -143,10 +143,11 @@ func AdapterBids() []AdapterBid { // Adapter execution status const ( - AdapterErrorBadInput AdapterError = "badinput" - AdapterErrorBadServerResponse AdapterError = "badserverresponse" - AdapterErrorTimeout AdapterError = "timeout" - AdapterErrorUnknown AdapterError = "unknown_error" + AdapterErrorBadInput AdapterError = "badinput" + AdapterErrorBadServerResponse AdapterError = "badserverresponse" + AdapterErrorTimeout AdapterError = "timeout" + AdapterErrorFailedToRequestBids AdapterError = "failedtorequestbid" + AdapterErrorUnknown AdapterError = "unknown_error" ) func AdapterErrors() []AdapterError { @@ -154,6 +155,7 @@ func AdapterErrors() []AdapterError { AdapterErrorBadInput, AdapterErrorBadServerResponse, AdapterErrorTimeout, + AdapterErrorFailedToRequestBids, AdapterErrorUnknown, } }