exception handling
All custom types are in pyjiit/exceptions.py. They are empty subclasses. Messages come from __hit (pformat of status) or from download_marks.
classDiagram class Exception class APIError class LoginError class SessionError class SessionExpired class NotLoggedIn class AccountAPIError Exception <|-- APIError APIError <|-- LoginError Exception <|-- SessionError SessionError <|-- SessionExpired SessionError <|-- NotLoggedIn Exception <|-- AccountAPIError
SessionError is not raised directly. Catch it to cover both NotLoggedIn and SessionExpired. APIError does not catch session errors.
APIError#
Default for __hit when responseStatus != "Success". Also raised by download_marks on non-200.
Typical: bad parameters, portal Failure payloads, empty fines queue (NO APPROVED REQUEST FOUND).
LoginError#
Subclass of APIError. Passed as exception=LoginError on both login POSTs. Bad password, bad captcha, locked account, anything those endpoints put in status.
SessionError#
Base for session problems. Unused as a raise type.
SessionExpired#
__hit when type(resp["status"]) is int and resp["status"] == 401. Message is resp["error"]. The decorator’s expiry check is commented out, so this is the live path.
NotLoggedIn#
@authenticated when self.session is None. No message.
AccountAPIError#
set_password only (exception=AccountAPIError). Sibling of APIError, not a subclass. Catch both if you treat all portal failures the same.
flowchart TD
Call["Webportal method"] --> Sess{"session is None and decorated?"}
Sess -->|yes| NL["NotLoggedIn"]
Sess --> HTTP["HTTP"]
HTTP --> I401{"status is int 401?"}
I401 -->|yes| SE["SessionExpired"]
HTTP --> RS{"responseStatus Success?"}
RS -->|no| Kind{"exception kwarg"}
Kind -->|login| LE["LoginError"]
Kind -->|set_password| AE["AccountAPIError"]
Kind -->|default| API["APIError"]Catching#
from pyjiit.exceptions import (
APIError,
LoginError,
SessionError,
SessionExpired,
NotLoggedIn,
AccountAPIError,
)
try:
w.student_login(user, password, captcha)
w.get_attendance_meta()
w.set_password(old, new)
except LoginError:
...
except NotLoggedIn:
...
except SessionExpired:
...
except AccountAPIError:
...
except APIError:
...
except SessionError:
...
Order matters: LoginError before APIError. NotLoggedIn / SessionExpired before SessionError.
flowchart LR L["LoginError"] --> A["APIError"] NL["NotLoggedIn"] --> S["SessionError"] SE["SessionExpired"] --> S AE["AccountAPIError"] --> E["Exception"]