diff --git a/src/validation/errors.go b/src/validation/errors.go index c0621f73..b0dfb3c7 100644 --- a/src/validation/errors.go +++ b/src/validation/errors.go @@ -197,6 +197,21 @@ var ( // ErrorMaintenanceMode will be sent if there is ongoing maintenance // Code: 20005 ErrorMaintenanceMode = Error{errors.New("maintenance mode active")} + + // ErrStatusForbidden will be sent if tibia sent us a 403 response. + // This usually happens when we are rate limited. + // Code: 20006 + ErrStatusForbidden = Error{errors.New("got status forbidden from tibia.com")} + + // ErrStatusForbidden will be sent if tibia sent us a 302 response, but it + // is not in MaintenanceMode. Because if it were, we would throw a + // ErrorMaintenanceMode. + // Code: 20007 + ErrStatusFound = Error{errors.New("got status found from tibia.com")} + + // ErrStatusUnknown will be sent a HTTP request we are not expecting. + // Code: 20008 + ErrStatusUnknown = Error{errors.New("got unknown status from tibia.com")} ) // Code will return the code of the error @@ -290,6 +305,12 @@ func (e Error) Code() int { return 20004 case ErrorMaintenanceMode: return 20005 + case ErrStatusForbidden: + return 20006 + case ErrStatusFound: + return 20007 + case ErrStatusUnknown: + return 20008 default: return 0 } diff --git a/src/webserver.go b/src/webserver.go index 70e5f39a..b3210069 100644 --- a/src/webserver.go +++ b/src/webserver.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "errors" + "fmt" "log" "net/http" "os" @@ -1087,13 +1088,17 @@ func TibiaDataErrorHandler(c *gin.Context, err error, httpCode int) { if httpCode == 0 { if t.Code() == 10 || t.Code() == 11 { httpCode = http.StatusInternalServerError - info.Status.HTTPCode = httpCode } else { httpCode = http.StatusBadRequest - info.Status.HTTPCode = httpCode } } + // An error occurred at tibia.com + if t.Code() > 20000 { + httpCode = http.StatusBadGateway + } + + info.Status.HTTPCode = httpCode info.Status.Error = t.Code() info.Status.Message = t.Error() case error: @@ -1225,29 +1230,39 @@ func TibiaDataHTMLDataCollector(TibiaDataRequest TibiaDataRequestStruct) (string if err != nil { log.Printf("[error] TibiaDataHTMLDataCollector (Status: %s, URL: %s) in resp1: %s", res.Status(), res.Request.URL, err) + return "", err + } - switch res.StatusCode() { - case http.StatusForbidden: - // throttled request - LogMessage = "request throttled due to rate-limitation on tibia.com" - log.Printf("[warning] TibiaDataHTMLDataCollector: %s!", LogMessage) - return "", err - - case http.StatusFound: - // Check if page is in maintenance mode - location, _ := res.RawResponse.Location() - if location != nil && location.Host == "maintenance.tibia.com" { - LogMessage := "maintenance mode detected on tibia.com" - log.Printf("[info] TibiaDataHTMLDataCollector: %s!", LogMessage) - return "", validation.ErrorMaintenanceMode - } - fallthrough - - default: - LogMessage = "unknown error occurred on tibia.com" - log.Printf("[error] TibiaDataHTMLDataCollector: %s!", LogMessage) - return "", err + switch res.StatusCode() { + case http.StatusOK: + // ok request, nothing to be done + case http.StatusForbidden: + // throttled request + LogMessage = "request throttled due to rate-limitation on tibia.com" + log.Printf("[warning] TibiaDataHTMLDataCollector: %s!", LogMessage) + return "", validation.ErrStatusForbidden + case http.StatusFound: + // Check if page is in maintenance mode + location, _ := res.RawResponse.Location() + if location != nil && location.Host == "maintenance.tibia.com" { + LogMessage := "maintenance mode detected on tibia.com" + log.Printf("[info] TibiaDataHTMLDataCollector: %s!", LogMessage) + return "", validation.ErrorMaintenanceMode } + + LogMessage = fmt.Sprintf( + "unknown error occurred on tibia.com (Status: %d, RequestURL: %s)", + http.StatusFound, res.Request.URL, + ) + log.Printf("[error] TibiaDataHTMLDataCollector: %s!", LogMessage) + return "", validation.ErrStatusFound + default: + LogMessage = fmt.Sprintf( + "unknown error and status occurred on tibia.com (Status: %d, RequestURL: %s)", + res.StatusCode(), res.Request.URL, + ) + log.Printf("[error] TibiaDataHTMLDataCollector: %s!", LogMessage) + return "", validation.ErrStatusUnknown } if TibiaDataRequest.RawBody { diff --git a/src/webserver_test.go b/src/webserver_test.go index ae49660d..56f28eba 100644 --- a/src/webserver_test.go +++ b/src/webserver_test.go @@ -282,4 +282,19 @@ func TestErrorHandler(t *testing.T) { c, _ = gin.CreateTestContext(w) TibiaDataErrorHandler(c, errors.New("test error"), 0) assert.Equal(http.StatusBadGateway, w.Code) + + w = httptest.NewRecorder() + c, _ = gin.CreateTestContext(w) + TibiaDataErrorHandler(c, validation.ErrStatusForbidden, http.StatusForbidden) + assert.Equal(http.StatusBadGateway, w.Code) + + w = httptest.NewRecorder() + c, _ = gin.CreateTestContext(w) + TibiaDataErrorHandler(c, validation.ErrStatusFound, http.StatusFound) + assert.Equal(http.StatusBadGateway, w.Code) + + w = httptest.NewRecorder() + c, _ = gin.CreateTestContext(w) + TibiaDataErrorHandler(c, validation.ErrStatusUnknown, http.StatusConflict) + assert.Equal(http.StatusBadGateway, w.Code) }