Skip to content

Failure to decode Json response from Typesense #82

@imurraywano

Description

@imurraywano

As of the current version, in the case of Typesense returning an error message with a Json-like component, the Python client fails to decode the response (i.e. response.json()).

See trace below:

│ /usr/local/python/3.11.12/lib/python3.11/site-packages/typesense/api_call.py:479 in _make_request_and_process_response                           │
│                                                                                                                                                  │
│   476 │   │   **kwargs: SessionFunctionKwargs[TParams, TBody],                                                                                   │
│   477 │   ) -> typing.Union[TEntityDict, str]:                                                                                                   │
│   478 │   │   """Make the API request and process the response."""                                                                               │
│ ❱ 479 │   │   request_response = self.request_handler.make_request(                                                                              │
│   480 │   │   │   fn=fn,                                                                                                                         │
│   481 │   │   │   url=url,                                                                                                                       │
│   482 │   │   │   as_json=as_json,                                                                                                               │
│                                                                                                                                                  │
│ /usr/local/python/3.11.12/lib/python3.11/site-packages/typesense/request_handler.py:221 in make_request                                          │
│                                                                                                                                                  │
│   218 │   │   response = fn(url, **kwargs)                                                                                                       │
│   219 │   │                                                                                                                                      │
│   220 │   │   if response.status_code < 200 or response.status_code >= 300:                                                                      │
│ ❱ 221 │   │   │   error_message = self._get_error_message(response)                                                                              │
│   222 │   │   │   raise self._get_exception(response.status_code)(                                                                               │
│   223 │   │   │   │   response.status_code,                                                                                                      │
│   224 │   │   │   │   error_message,                                                                                                             │
│                                                                                                                                                  │
│ /usr/local/python/3.11.12/lib/python3.11/site-packages/typesense/request_handler.py:263 in _get_error_message                                    │
│                                                                                                                                                  │
│   260 │   │   """                                                                                                                                │
│   261 │   │   content_type = response.headers.get("Content-Type", "")                                                                            │
│   262 │   │   if content_type.startswith("application/json"):                                                                                    │
│ ❱ 263 │   │   │   err_message: str = response.json().get("message", "API error.")                                                                │
│   264 │   │   │   return err_message                                                                                                             │
│   265 │   │   return "API error."                                                                                                                │
│   266                                                                                                                                            │
│                                                                                                                                                  │
│ /usr/local/python/3.11.12/lib/python3.11/site-packages/requests/models.py:978 in json                                                            │
│                                                                                                                                                  │
│    975 │   │   except JSONDecodeError as e:                                                                                                      │
│    976 │   │   │   # Catch JSON-related errors and raise as requests.JSONDecodeError                                                             │
│    977 │   │   │   # This aliases json.JSONDecodeError and simplejson.JSONDecodeError                                                            │
│ ❱  978 │   │   │   raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)                                                                            │
│    979 │                                                                                                                                         │
│    980 │   @property                                                                                                                             │
│    981 │   def links(self):                                                                                                                      │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
JSONDecodeError: Expecting ',' delimiter: line 1 column 34 (char 33)

Solution:

  1. Can add additional error handling for this step. with a try/except block around decoding the response, i.e.
@staticmethod
def patched_get_error_message(response: requests.Response) -> str:
    """
    Extract the error message from an API response.

    Args:
        response (requests.Response): The API response.

    Returns:
        str: The extracted error message or a default message.
    """
    content_type = response.headers.get("Content-Type", "")
    if content_type.startswith("application/json"):
        try:
            err_message: str = response.json().get("message", "API error.")
            return err_message
        except requests.exceptions.JSONDecodeError:
            return f"API error: Invalid JSON response: {response.text}"
    return "API error."
  1. Escape returned error messages. For this particular case, the message was: {"message": "OpenAI API error: {"detail":"Failed to get response from Azure OpenAI API"}"}. And Typesense is version 28.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions