Skip to content

Commit dbb6970

Browse files
authored
Error handling updated for remaining user_mgt APIs (#315)
* Error handling updated for remaining user_mgt APIs * Removed unused constants
1 parent 3361452 commit dbb6970

File tree

3 files changed

+35
-40
lines changed

3 files changed

+35
-40
lines changed

firebase_admin/_user_mgt.py

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
from firebase_admin import _user_import
2525

2626

27-
USER_IMPORT_ERROR = 'USER_IMPORT_ERROR'
28-
USER_DOWNLOAD_ERROR = 'LIST_USERS_ERROR'
29-
3027
MAX_LIST_USERS_RESULTS = 1000
3128
MAX_IMPORT_USERS_SIZE = 1000
3229

@@ -44,15 +41,6 @@ def __init__(self, description):
4441
DELETE_ATTRIBUTE = Sentinel('Value used to delete an attribute from a user profile')
4542

4643

47-
class ApiCallError(Exception):
48-
"""Represents an Exception encountered while invoking the Firebase user management API."""
49-
50-
def __init__(self, code, message, error=None):
51-
Exception.__init__(self, message)
52-
self.code = code
53-
self.detail = error
54-
55-
5644
class UserMetadata(object):
5745
"""Contains additional metadata associated with a user account."""
5846

@@ -510,7 +498,7 @@ def list_users(self, page_token=None, max_results=MAX_LIST_USERS_RESULTS):
510498
try:
511499
return self._client.body('get', '/accounts:batchGet', params=payload)
512500
except requests.exceptions.RequestException as error:
513-
self._handle_http_error(USER_DOWNLOAD_ERROR, 'Failed to download user accounts.', error)
501+
raise _auth_utils.handle_auth_backend_error(error)
514502

515503
def create_user(self, uid=None, display_name=None, email=None, phone_number=None,
516504
photo_url=None, password=None, disabled=None, email_verified=None):
@@ -619,13 +607,15 @@ def import_users(self, users, hash_alg=None):
619607
raise ValueError('A UserImportHash is required to import users with passwords.')
620608
payload.update(hash_alg.to_dict())
621609
try:
622-
response = self._client.body('post', '/accounts:batchCreate', json=payload)
610+
body, http_resp = self._client.body_and_response(
611+
'post', '/accounts:batchCreate', json=payload)
623612
except requests.exceptions.RequestException as error:
624-
self._handle_http_error(USER_IMPORT_ERROR, 'Failed to import users.', error)
613+
raise _auth_utils.handle_auth_backend_error(error)
625614
else:
626-
if not isinstance(response, dict):
627-
raise ApiCallError(USER_IMPORT_ERROR, 'Failed to import users.')
628-
return response
615+
if not isinstance(body, dict):
616+
raise _auth_utils.UnexpectedResponseError(
617+
'Failed to import users.', http_response=http_resp)
618+
return body
629619

630620
def generate_email_action_link(self, action_type, email, action_code_settings=None):
631621
"""Fetches the email action links for types
@@ -640,7 +630,7 @@ def generate_email_action_link(self, action_type, email, action_code_settings=No
640630
link_url: action url to be emailed to the user
641631
642632
Raises:
643-
ApiCallError: If an error occurs while generating the link
633+
FirebaseError: If an error occurs while generating the link
644634
ValueError: If the provided arguments are invalid
645635
"""
646636
payload = {
@@ -663,13 +653,6 @@ def generate_email_action_link(self, action_type, email, action_code_settings=No
663653
'Failed to generate email action link.', http_response=http_resp)
664654
return body.get('oobLink')
665655

666-
def _handle_http_error(self, code, msg, error):
667-
if error.response is not None:
668-
msg += '\nServer response: {0}'.format(error.response.content.decode())
669-
else:
670-
msg += '\nReason: {0}'.format(error)
671-
raise ApiCallError(code, msg, error)
672-
673656

674657
class _UserIterator(object):
675658
"""An iterator that allows iterating over user accounts, one at a time.

firebase_admin/auth.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -308,14 +308,11 @@ def list_users(page_token=None, max_results=_user_mgt.MAX_LIST_USERS_RESULTS, ap
308308
309309
Raises:
310310
ValueError: If max_results or page_token are invalid.
311-
AuthError: If an error occurs while retrieving the user accounts.
311+
FirebaseError: If an error occurs while retrieving the user accounts.
312312
"""
313313
user_manager = _get_auth_service(app).user_manager
314314
def download(page_token, max_results):
315-
try:
316-
return user_manager.list_users(page_token, max_results)
317-
except _user_mgt.ApiCallError as error:
318-
raise AuthError(error.code, str(error), error.detail)
315+
return user_manager.list_users(page_token, max_results)
319316
return ListUsersPage(download, page_token, max_results)
320317

321318

@@ -443,14 +440,11 @@ def import_users(users, hash_alg=None, app=None):
443440
444441
Raises:
445442
ValueError: If the provided arguments are invalid.
446-
AuthError: If an error occurs while importing users.
443+
FirebaseError: If an error occurs while importing users.
447444
"""
448445
user_manager = _get_auth_service(app).user_manager
449-
try:
450-
result = user_manager.import_users(users, hash_alg)
451-
return UserImportResult(result, len(users))
452-
except _user_mgt.ApiCallError as error:
453-
raise AuthError(error.code, str(error), error.detail)
446+
result = user_manager.import_users(users, hash_alg)
447+
return UserImportResult(result, len(users))
454448

455449

456450
def generate_password_reset_link(email, action_code_settings=None, app=None):

tests/test_user_mgt.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -731,10 +731,9 @@ def test_list_users_with_all_args(self, user_mgt_app):
731731

732732
def test_list_users_error(self, user_mgt_app):
733733
_instrument_user_manager(user_mgt_app, 500, '{"error":"test"}')
734-
with pytest.raises(auth.AuthError) as excinfo:
734+
with pytest.raises(exceptions.InternalError) as excinfo:
735735
auth.list_users(app=user_mgt_app)
736-
assert excinfo.value.code == _user_mgt.USER_DOWNLOAD_ERROR
737-
assert '{"error":"test"}' in str(excinfo.value)
736+
assert str(excinfo.value) == 'Unexpected error response: {"error":"test"}'
738737

739738
def _check_page(self, page):
740739
assert isinstance(page, auth.ListUsersPage)
@@ -1076,6 +1075,25 @@ def test_import_users_with_hash(self, user_mgt_app):
10761075
}
10771076
self._check_rpc_calls(recorder, expected)
10781077

1078+
def test_import_users_http_error(self, user_mgt_app):
1079+
_instrument_user_manager(user_mgt_app, 401, '{"error": {"message": "ERROR_CODE"}}')
1080+
users = [
1081+
auth.ImportUserRecord(uid='user1'),
1082+
auth.ImportUserRecord(uid='user2'),
1083+
]
1084+
with pytest.raises(exceptions.UnauthenticatedError) as excinfo:
1085+
auth.import_users(users, app=user_mgt_app)
1086+
assert str(excinfo.value) == 'Error while calling Auth service (ERROR_CODE).'
1087+
1088+
def test_import_users_unexpected_response(self, user_mgt_app):
1089+
_instrument_user_manager(user_mgt_app, 200, '"not dict"')
1090+
users = [
1091+
auth.ImportUserRecord(uid='user1'),
1092+
auth.ImportUserRecord(uid='user2'),
1093+
]
1094+
with pytest.raises(auth.UnexpectedResponseError):
1095+
auth.import_users(users, app=user_mgt_app)
1096+
10791097
def _check_rpc_calls(self, recorder, expected):
10801098
assert len(recorder) == 1
10811099
request = json.loads(recorder[0].body.decode())

0 commit comments

Comments
 (0)