Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions typesense/multi_search.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ func (m *multiSearch) Perform(ctx context.Context, commonSearchParams *api.Multi
if err != nil {
return nil, err
}
if err := multiSearchTopLevelError(response); err != nil {
return nil, err
}
if response.JSON200 == nil {
return nil, &HTTPError{Status: response.StatusCode(), Body: response.Body}
}
Expand All @@ -41,8 +44,30 @@ func (m *multiSearch) PerformWithContentType(ctx context.Context, commonSearchPa
if err != nil {
return nil, err
}
if err := multiSearchTopLevelError(response); err != nil {
return nil, err
}
if response.Body == nil {
return nil, &HTTPError{Status: response.StatusCode(), Body: response.Body}
}
return response, nil
}

func multiSearchTopLevelError(response *api.MultiSearchResponse) error {
if response == nil || len(response.Body) == 0 {
return nil
}

var errorResponse struct {
Code *int `json:"code"`
Error *string `json:"error"`
}
if err := json.Unmarshal(response.Body, &errorResponse); err != nil {
return nil
}
if errorResponse.Code == nil || errorResponse.Error == nil {
return nil
}

return &HTTPError{Status: *errorResponse.Code, Body: response.Body}
}
61 changes: 61 additions & 0 deletions typesense/multi_search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,67 @@ func TestMultiSearchOnHttpStatusErrorCodeReturnsError(t *testing.T) {
assert.NotNil(t, err)
}

func TestMultiSearchOnTopLevelErrorResponseReturnsError(t *testing.T) {
expectedParams := newMultiSearchParams()
expectedBody := newMultiSearchBodyParams()
responseBody := []byte(`{"code":404,"error":"` + "`non-existent`" + ` collection not found."}`)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockAPIClient := mocks.NewMockAPIClientInterface(ctrl)

mockAPIClient.EXPECT().
MultiSearchWithResponse(gomock.Not(gomock.Nil()), expectedParams, api.MultiSearchJSONRequestBody(expectedBody)).
Return(&api.MultiSearchResponse{
HTTPResponse: &http.Response{
StatusCode: http.StatusOK,
},
Body: responseBody,
JSON200: &api.MultiSearchResult{
Results: nil,
},
}, nil).Times(1)

client := NewClient(WithAPIClient(mockAPIClient))
params := newMultiSearchParams()
_, err := client.MultiSearch.Perform(context.Background(), params, newMultiSearchBodyParams())

var httpErr *HTTPError
assert.ErrorAs(t, err, &httpErr)
assert.Equal(t, 404, httpErr.Status)
assert.Equal(t, responseBody, httpErr.Body)
}

func TestMultiSearchWithContentTypeOnTopLevelErrorResponseReturnsError(t *testing.T) {
expectedParams := newMultiSearchParams()
expectedBody := newMultiSearchBodyParams()
expectedContentType := "application/x-json-stream"
responseBody := []byte(`{"code":422,"error":"Only upto 250 hits can be fetched per page."}`)
expectedReqBody, err := json.Marshal(expectedBody)
assert.Nil(t, err)
reqReader := bytes.NewReader(expectedReqBody)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockAPIClient := mocks.NewMockAPIClientInterface(ctrl)

mockAPIClient.EXPECT().
MultiSearchWithBodyWithResponse(gomock.Not(gomock.Nil()), expectedParams, expectedContentType, reqReader).
Return(&api.MultiSearchResponse{
HTTPResponse: &http.Response{
StatusCode: http.StatusOK,
},
Body: responseBody,
}, nil).Times(1)

client := NewClient(WithAPIClient(mockAPIClient))
params := newMultiSearchParams()
_, err = client.MultiSearch.PerformWithContentType(context.Background(), params, newMultiSearchBodyParams(), expectedContentType)

var httpErr *HTTPError
assert.ErrorAs(t, err, &httpErr)
assert.Equal(t, 422, httpErr.Status)
assert.Equal(t, responseBody, httpErr.Body)
}

func TestMultiSearchOnApiClientError(t *testing.T) {
expectedParams := newMultiSearchParams()
expectedBody := newMultiSearchBodyParams()
Expand Down
27 changes: 27 additions & 0 deletions typesense/test/multi_search_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ package test

import (
"context"
"errors"
"testing"

"github.com/stretchr/testify/require"
"github.com/typesense/typesense-go/v4/typesense"
"github.com/typesense/typesense-go/v4/typesense/api"
"github.com/typesense/typesense-go/v4/typesense/api/pointer"
)
Expand Down Expand Up @@ -86,6 +88,31 @@ func TestMultiSearch(t *testing.T) {
}
}

func TestMultiSearchUnionTopLevelErrorReturnsHTTPError(t *testing.T) {
_, err := typesenseClient.MultiSearch.Perform(
context.Background(),
&api.MultiSearchParams{
Q: pointer.String("query"),
},
api.MultiSearchSearchesParameter{
Searches: []api.MultiSearchCollectionParameters{
{
Collection: pointer.String("non-existent"),
},
},
Union: pointer.True(),
},
)
require.Error(t, err)

var httpErr *typesense.HTTPError
require.True(t, errors.As(err, &httpErr))
require.Equal(t, 404, httpErr.Status)
require.Contains(t, string(httpErr.Body), `"code"`)
require.Contains(t, string(httpErr.Body), `"error"`)
require.Contains(t, string(httpErr.Body), "collection not found")
}

func TestMultiSearchGroupBy(t *testing.T) {
collectionName1 := createNewCollection(t, "companies")
documents := []interface{}{
Expand Down
Loading