mirror of
https://github.com/elyby/chrly.git
synced 2024-12-24 05:59:54 +05:30
#1: Add case when Mojang's API returns empty response
This commit is contained in:
parent
e7c0fac346
commit
c2921400b0
@ -28,6 +28,8 @@ type ProfileInfo struct {
|
|||||||
IsDemo bool `json:"demo,omitempty"`
|
IsDemo bool `json:"demo,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exchanges usernames array to array of uuids
|
||||||
|
// See https://wiki.vg/Mojang_API#Playernames_-.3E_UUIDs
|
||||||
func UsernamesToUuids(usernames []string) ([]*ProfileInfo, error) {
|
func UsernamesToUuids(usernames []string) ([]*ProfileInfo, error) {
|
||||||
requestBody, _ := json.Marshal(usernames)
|
requestBody, _ := json.Marshal(usernames)
|
||||||
request, err := http.NewRequest("POST", "https://api.mojang.com/profiles/minecraft", bytes.NewBuffer(requestBody))
|
request, err := http.NewRequest("POST", "https://api.mojang.com/profiles/minecraft", bytes.NewBuffer(requestBody))
|
||||||
@ -43,8 +45,8 @@ func UsernamesToUuids(usernames []string) ([]*ProfileInfo, error) {
|
|||||||
}
|
}
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
|
|
||||||
if response.StatusCode == 429 {
|
if responseErr := validateResponse(response); responseErr != nil {
|
||||||
return nil, &TooManyRequestsError{}
|
return nil, responseErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var result []*ProfileInfo
|
var result []*ProfileInfo
|
||||||
@ -55,6 +57,8 @@ func UsernamesToUuids(usernames []string) ([]*ProfileInfo, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Obtains textures information for provided uuid
|
||||||
|
// See https://wiki.vg/Mojang_API#UUID_-.3E_Profile_.2B_Skin.2FCape
|
||||||
func UuidToTextures(uuid string, signed bool) (*SignedTexturesResponse, error) {
|
func UuidToTextures(uuid string, signed bool) (*SignedTexturesResponse, error) {
|
||||||
url := "https://sessionserver.mojang.com/session/minecraft/profile/" + uuid
|
url := "https://sessionserver.mojang.com/session/minecraft/profile/" + uuid
|
||||||
if signed {
|
if signed {
|
||||||
@ -72,8 +76,8 @@ func UuidToTextures(uuid string, signed bool) (*SignedTexturesResponse, error) {
|
|||||||
}
|
}
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
|
|
||||||
if response.StatusCode == 429 {
|
if responseErr := validateResponse(response); responseErr != nil {
|
||||||
return nil, &TooManyRequestsError{}
|
return nil, responseErr
|
||||||
}
|
}
|
||||||
|
|
||||||
var result *SignedTexturesResponse
|
var result *SignedTexturesResponse
|
||||||
@ -84,9 +88,30 @@ func UuidToTextures(uuid string, signed bool) (*SignedTexturesResponse, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateResponse(response *http.Response) error {
|
||||||
|
switch response.StatusCode {
|
||||||
|
case 204:
|
||||||
|
return &EmptyResponse{}
|
||||||
|
case 429:
|
||||||
|
return &TooManyRequestsError{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mojang API doesn't return a 404 Not Found error for non-existent data identifiers
|
||||||
|
// Instead, they return 204 with an empty body
|
||||||
|
type EmptyResponse struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*EmptyResponse) Error() string {
|
||||||
|
return "Empty Response"
|
||||||
|
}
|
||||||
|
|
||||||
|
// When you exceed the set limit of requests, this error will be returned
|
||||||
type TooManyRequestsError struct {
|
type TooManyRequestsError struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *TooManyRequestsError) Error() string {
|
func (*TooManyRequestsError) Error() string {
|
||||||
return "Too Many Requests"
|
return "Too Many Requests"
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,27 @@ func TestUuidToTextures(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("handle too many requests error", func(t *testing.T) {
|
t.Run("handle empty response", func(t *testing.T) {
|
||||||
|
assert := testify.New(t)
|
||||||
|
|
||||||
|
defer gock.Off()
|
||||||
|
gock.New("https://sessionserver.mojang.com").
|
||||||
|
Get("/session/minecraft/profile/4566e69fc90748ee8d71d7ba5aa00d20").
|
||||||
|
Reply(204).
|
||||||
|
BodyString("")
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
gock.InterceptClient(client)
|
||||||
|
|
||||||
|
HttpClient = client
|
||||||
|
|
||||||
|
result, err := UuidToTextures("4566e69fc90748ee8d71d7ba5aa00d20", false)
|
||||||
|
assert.Nil(result)
|
||||||
|
assert.IsType(&EmptyResponse{}, err)
|
||||||
|
assert.EqualError(err, "Empty Response")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("handle too many requests response", func(t *testing.T) {
|
||||||
assert := testify.New(t)
|
assert := testify.New(t)
|
||||||
|
|
||||||
defer gock.Off()
|
defer gock.Off()
|
||||||
|
@ -146,12 +146,12 @@ func (ctx *JobsQueue) getTextures(uuid string) *mojang.SignedTexturesResponse {
|
|||||||
|
|
||||||
shouldCache := true
|
shouldCache := true
|
||||||
result, err := uuidToTextures(uuid, true)
|
result, err := uuidToTextures(uuid, true)
|
||||||
if err != nil {
|
switch err.(type) {
|
||||||
if _, ok := err.(*mojang.TooManyRequestsError); !ok {
|
case *mojang.EmptyResponse:
|
||||||
panic(err)
|
case *mojang.TooManyRequestsError:
|
||||||
}
|
|
||||||
|
|
||||||
shouldCache = false
|
shouldCache = false
|
||||||
|
case error:
|
||||||
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if shouldCache && result != nil {
|
if shouldCache && result != nil {
|
||||||
|
@ -293,7 +293,7 @@ func (suite *QueueTestSuite) TestDoNothingWhenNoTasks() {
|
|||||||
suite.Iterate()
|
suite.Iterate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestHandle429ResponseWhenExchangingUsernamesToUuids() {
|
func (suite *QueueTestSuite) TestHandleTooManyRequestsResponseWhenExchangingUsernamesToUuids() {
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
||||||
// Storage.StoreUuid, Storage.GetTextures and Storage.StoreTextures shouldn't be called
|
// Storage.StoreUuid, Storage.GetTextures and Storage.StoreTextures shouldn't be called
|
||||||
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb"}).Once().Return(nil, &mojang.TooManyRequestsError{})
|
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb"}).Once().Return(nil, &mojang.TooManyRequestsError{})
|
||||||
@ -305,7 +305,27 @@ func (suite *QueueTestSuite) TestHandle429ResponseWhenExchangingUsernamesToUuids
|
|||||||
suite.Assert().Nil(<-resultChan)
|
suite.Assert().Nil(<-resultChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestHandle429ResponseWhenRequestingUsersTextures() {
|
func (suite *QueueTestSuite) TestHandleEmptyResponseWhenRequestingUsersTextures() {
|
||||||
|
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
||||||
|
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
||||||
|
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
||||||
|
// Storage.StoreTextures shouldn't be called
|
||||||
|
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
|
||||||
|
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
||||||
|
}, nil)
|
||||||
|
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(
|
||||||
|
nil,
|
||||||
|
&mojang.EmptyResponse{},
|
||||||
|
)
|
||||||
|
|
||||||
|
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
||||||
|
|
||||||
|
suite.Iterate()
|
||||||
|
|
||||||
|
suite.Assert().Nil(<-resultChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (suite *QueueTestSuite) TestHandleTooManyRequestsResponseWhenRequestingUsersTextures() {
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
||||||
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
||||||
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
||||||
|
Loading…
Reference in New Issue
Block a user