12
12
from pandas import DataFrame
13
13
from requests import Session
14
14
from requests .models import Response
15
- from requests .exceptions import ConnectionError
15
+ from requests .exceptions import ConnectionError , HTTPError , JSONDecodeError
16
16
from requests .adapters import HTTPAdapter
17
17
from urllib3 .util import Retry
18
18
from tenacity import retry , wait_exponential , stop_after_attempt
19
19
from time import sleep
20
20
21
+ from vespa .exceptions import VespaError
21
22
from vespa .io import VespaQueryResponse , VespaResponse
22
23
from vespa .package import ApplicationPackage
23
24
@@ -55,6 +56,29 @@ def parse_feed_df(df: DataFrame, include_id: bool, id_field="id") -> List[Dict[s
55
56
return batch
56
57
57
58
59
+ def raise_for_status (response : Response ) -> None :
60
+ """
61
+ Raises an appropriate error if necessary.
62
+
63
+ If the response contains an error message, VespaError is raised along with HTTPError to provide more details.
64
+
65
+ :param response: Response object from Vespa API.
66
+ :raises HTTPError: If status_code is between 400 and 599.
67
+ :raises VespaError: If the response JSON contains an error message.
68
+ """
69
+ try :
70
+ response .raise_for_status ()
71
+ except HTTPError as http_error :
72
+ try :
73
+ response_json = response .json ()
74
+ except JSONDecodeError :
75
+ raise http_error
76
+ errors = response_json .get ("root" , {}).get ("errors" , [])
77
+ if not errors :
78
+ raise http_error
79
+ raise VespaError (errors ) from http_error
80
+
81
+
58
82
class Vespa (object ):
59
83
def __init__ (
60
84
self ,
@@ -836,7 +860,7 @@ def feed_data_point(
836
860
)
837
861
vespa_format = {"fields" : fields }
838
862
response = self .http_session .post (end_point , json = vespa_format , cert = self .cert )
839
- response . raise_for_status ()
863
+ raise_for_status (response )
840
864
return VespaResponse (
841
865
json = response .json (),
842
866
status_code = response .status_code ,
@@ -858,7 +882,7 @@ def query(
858
882
:raises HTTPError: if one occurred
859
883
"""
860
884
response = self .http_session .post (self .app .search_end_point , json = body , cert = self .cert )
861
- response . raise_for_status ()
885
+ raise_for_status (response )
862
886
return VespaQueryResponse (
863
887
json = response .json (), status_code = response .status_code , url = str (response .url )
864
888
)
@@ -882,7 +906,7 @@ def delete_data(
882
906
self .app .end_point , namespace , schema , str (data_id )
883
907
)
884
908
response = self .http_session .delete (end_point , cert = self .cert )
885
- response . raise_for_status ()
909
+ raise_for_status (response )
886
910
return VespaResponse (
887
911
json = response .json (),
888
912
status_code = response .status_code ,
@@ -909,7 +933,7 @@ def delete_all_docs(
909
933
self .app .end_point , namespace , schema , content_cluster_name
910
934
)
911
935
response = self .http_session .delete (end_point , cert = self .cert )
912
- response . raise_for_status ()
936
+ raise_for_status (response )
913
937
return response
914
938
915
939
def get_data (
@@ -931,7 +955,7 @@ def get_data(
931
955
self .app .end_point , namespace , schema , str (data_id )
932
956
)
933
957
response = self .http_session .get (end_point , cert = self .cert )
934
- response . raise_for_status ()
958
+ raise_for_status (response )
935
959
return VespaResponse (
936
960
json = response .json (),
937
961
status_code = response .status_code ,
@@ -966,7 +990,7 @@ def update_data(
966
990
)
967
991
vespa_format = {"fields" : {k : {"assign" : v } for k , v in fields .items ()}}
968
992
response = self .http_session .put (end_point , json = vespa_format , cert = self .cert )
969
- response . raise_for_status ()
993
+ raise_for_status (response )
970
994
return VespaResponse (
971
995
json = response .json (),
972
996
status_code = response .status_code ,
0 commit comments