From a7aa99bfe52be6c6b7c24a05e2db5ea280ec7264 Mon Sep 17 00:00:00 2001 From: Richard O'Dwyer Date: Wed, 23 Oct 2019 19:52:52 +0100 Subject: [PATCH] Adds code, message attrs to RequestError exception, makes message in raised exceptions include more details. --- HISTORY.rst | 1 + src/mega/errors.py | 78 ++++++++++++++++++++++++++++++++++++++-- src/tests/test_errors.py | 17 +++++++++ 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 0bc68d9..086829d 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -9,6 +9,7 @@ Release History - Removes broken method ``get_contacts()``. - Adds support for login with a v2 Mega user account. - Adds ``export()`` method to share a file or folder, returning public share URL with key. +- Adds code, message attrs to RequestError exception, makes message in raised exceptions include more details. 0.9.20 (2019-10-17) diff --git a/src/mega/errors.py b/src/mega/errors.py index d231381..4df7f90 100644 --- a/src/mega/errors.py +++ b/src/mega/errors.py @@ -5,9 +5,83 @@ class ValidationError(Exception): pass +_CODE_TO_DESCRIPTIONS = { + -1: ( + 'EINTERNAL', + ( + 'An internal error has occurred. Please submit a bug report, ' + 'detailing the exact circumstances in which this error occurred' + ) + ), + -2: ('EARGS', 'You have passed invalid arguments to this command'), + -3: ( + 'EAGAIN', + ( + '(always at the request level) A temporary congestion or server ' + 'malfunction prevented your request from being processed. ' + 'No data was altered. Retry. Retries must be spaced with ' + 'exponential backoff' + ) + ), + -4: ( + 'ERATELIMIT', + ( + 'You have exceeded your command weight per time quota. Please ' + 'wait a few seconds, then try again (this should never happen ' + 'in sane real-life applications)' + ) + ), + -5: ('EFAILED', 'The upload failed. Please restart it from scratch'), + -6: ( + 'ETOOMANY', + 'Too many concurrent IP addresses are accessing this upload target URL' + ), + -7: ( + 'ERANGE', + ( + 'The upload file packet is out of range or not starting and ' + 'ending on a chunk boundary' + ) + ), + -8: ( + 'EEXPIRED', + ( + 'The upload target URL you are trying to access has expired. ' + 'Please request a fresh one' + ) + ), + -9: ('ENOENT', 'Object (typically, node or user) not found'), + -10: ('ECIRCULAR', 'Circular linkage attempted'), + -11: ( + 'EACCESS', + 'Access violation (e.g., trying to write to a read-only share)' + ), + -12: ('EEXIST', 'Trying to create an object that already exists'), + -13: ('EINCOMPLETE', 'Trying to access an incomplete resource'), + -14: ('EKEY', 'A decryption operation failed (never returned by the API)'), + -15: ('ESID', 'Invalid or expired user session, please relogin'), + -16: ('EBLOCKED', 'User blocked'), + -17: ('EOVERQUOTA', 'Request over quota'), + -18: ( + 'ETEMPUNAVAIL', + 'Resource temporarily not available, please try again later' + ), + -19: ('ETOOMANYCONNECTIONS', 'many connections on this resource'), + -20: ('EWRITE', 'Write failed'), + -21: ('EREAD', 'Read failed'), + -22: ('EAPPKEY', 'Invalid application key; request not processed'), +} + + class RequestError(Exception): """ Error in API request """ - # TODO add error response messages - pass + def __init__(self, message): + code = message + self.code = code + code_desc, long_desc = _CODE_TO_DESCRIPTIONS[code] + self.message = f'{code_desc}, {long_desc}' + + def __str__(self): + return self.message diff --git a/src/tests/test_errors.py b/src/tests/test_errors.py index e69de29..4469349 100644 --- a/src/tests/test_errors.py +++ b/src/tests/test_errors.py @@ -0,0 +1,17 @@ +import pytest + +from mega.errors import RequestError, _CODE_TO_DESCRIPTIONS + + +@pytest.mark.parametrize( + 'code, exp_message', [ + (code, f'{desc[0]}, {desc[1]}') + for code, desc in _CODE_TO_DESCRIPTIONS.items() + ] +) +def test_request_error(code, exp_message): + exc = RequestError(code) + + assert exc.code == code + assert exc.message == exp_message + assert str(exc) == exp_message