Skip to content

Commit 96ebb73

Browse files
committed
fix: list relations should not swallow errors
1 parent 172cd26 commit 96ebb73

File tree

6 files changed

+162
-28
lines changed

6 files changed

+162
-28
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# Changelog
22

3-
## [Unreleased](https://github.com/openfga/python-sdk/compare/v0.9.2...HEAD)
3+
## [Unreleased](https://github.com/openfga/python-sdk/compare/v0.9.3...HEAD)
44

55
### [0.9.3](https://github.com/openfga/python-sdk/compare/v0.9.2...v0.9.3) (2025-03-26)
66

7+
- fix: ListRelations should not swallow errors (#183)
78
- feat: feat: support List Stores name filter (#181)
89
- fix: urllib3 compatibility < v2 (#179)
910

openfga_sdk/client/client.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ def options_to_transaction_info(
144144
return WriteTransactionOpts()
145145

146146

147+
def _check_errored(response: ClientBatchCheckClientResponse):
148+
"""
149+
Helper function to return whether the response is errored
150+
"""
151+
return response.error is not None
152+
153+
147154
def _check_allowed(response: ClientBatchCheckClientResponse):
148155
"""
149156
Helper function to return whether the response is check is allowed
@@ -972,6 +979,13 @@ async def list_relations(
972979
for i in body.relations
973980
]
974981
result = await self.client_batch_check(request_body, options)
982+
983+
# filter out any errored responses and raise the first error
984+
errored_result_iterator = filter(_check_errored, result)
985+
errored_result_list = list(errored_result_iterator)
986+
if len(errored_result_list) > 0:
987+
raise errored_result_list[0].error
988+
975989
# need to filter with the allowed response
976990
result_iterator = filter(_check_allowed, result)
977991
result_list = list(result_iterator)

openfga_sdk/sync/client/client.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ def options_to_transaction_info(
145145
return WriteTransactionOpts()
146146

147147

148+
def _check_errored(response: ClientBatchCheckClientResponse):
149+
"""
150+
Helper function to return whether the response is errored
151+
"""
152+
return response.error is not None
153+
154+
148155
def _check_allowed(response: ClientBatchCheckClientResponse):
149156
"""
150157
Helper function to return whether the response is check is allowed
@@ -971,6 +978,13 @@ def list_relations(
971978
for i in body.relations
972979
]
973980
result = self.client_batch_check(request_body, options)
981+
982+
# filter out any errored responses and raise the first error
983+
errored_result_iterator = filter(_check_errored, result)
984+
errored_result_list = list(errored_result_iterator)
985+
if len(errored_result_list) > 0:
986+
raise errored_result_list[0].error
987+
974988
# need to filter with the allowed response
975989
result_iterator = filter(_check_allowed, result)
976990
result_list = list(result_iterator)

test/client/client_test.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2875,6 +2875,27 @@ async def test_list_relations_unauthorized(self, mock_request):
28752875
mock_request.assert_called()
28762876
await api_client.close()
28772877

2878+
@patch.object(rest.RESTClientObject, "request")
2879+
async def test_list_relations_errored(self, mock_request):
2880+
"""Test case for list relations with undefined exception"""
2881+
2882+
mock_request.side_effect = ValueError()
2883+
configuration = self.configuration
2884+
configuration.store_id = store_id
2885+
async with OpenFgaClient(configuration) as api_client:
2886+
with self.assertRaises(ValueError):
2887+
await api_client.list_relations(
2888+
body=ClientListRelationsRequest(
2889+
user="user:81684243-9356-4421-8fbf-a4f8d36aa31b",
2890+
relations=["reader", "owner", "viewer"],
2891+
object="document:2021-budget",
2892+
),
2893+
options={"authorization_model_id": "01GXSA8YR785C4FYS3C0RTG7B1"},
2894+
)
2895+
2896+
mock_request.assert_called()
2897+
await api_client.close()
2898+
28782899
@patch.object(rest.RESTClientObject, "request")
28792900
async def test_list_users(self, mock_request):
28802901
"""

test/sync/client/client_test.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2878,6 +2878,27 @@ def test_list_relations_unauthorized(self, mock_request):
28782878
mock_request.assert_called()
28792879
api_client.close()
28802880

2881+
@patch.object(rest.RESTClientObject, "request")
2882+
def test_list_relations_errored(self, mock_request):
2883+
"""Test case for list relations with undefined exception"""
2884+
2885+
mock_request.side_effect = ValueError()
2886+
configuration = self.configuration
2887+
configuration.store_id = store_id
2888+
with OpenFgaClient(configuration) as api_client:
2889+
with self.assertRaises(ValueError):
2890+
api_client.list_relations(
2891+
body=ClientListRelationsRequest(
2892+
user="user:81684243-9356-4421-8fbf-a4f8d36aa31b",
2893+
relations=["reader", "owner", "viewer"],
2894+
object="document:2021-budget",
2895+
),
2896+
options={"authorization_model_id": "01GXSA8YR785C4FYS3C0RTG7B1"},
2897+
)
2898+
2899+
mock_request.assert_called()
2900+
api_client.close()
2901+
28812902
@patch.object(rest.RESTClientObject, "request")
28822903
def test_list_users(self, mock_request):
28832904
"""

0 commit comments

Comments
 (0)