From b924ef588aba8a48e1f7e78846c686df517e8962 Mon Sep 17 00:00:00 2001 From: Hiro Date: Tue, 10 Mar 2026 10:40:25 +0000 Subject: [PATCH 1/2] fix(errors): standardize error handling with custom exception classes --- src/lighthouseweb3/functions/axios.py | 21 +++++++++++---------- src/lighthouseweb3/functions/deal_status.py | 3 ++- src/lighthouseweb3/functions/exceptions.py | 19 +++++++++++++++++++ src/lighthouseweb3/functions/upload.py | 7 +++---- 4 files changed, 35 insertions(+), 15 deletions(-) create mode 100644 src/lighthouseweb3/functions/exceptions.py diff --git a/src/lighthouseweb3/functions/axios.py b/src/lighthouseweb3/functions/axios.py index a50df40..6d2db3a 100644 --- a/src/lighthouseweb3/functions/axios.py +++ b/src/lighthouseweb3/functions/axios.py @@ -4,6 +4,7 @@ import json import requests as req from . import utils +from .exceptions import LighthouseAPIError class Axios: @@ -17,8 +18,8 @@ def parse_url_query(self, query): if query is not None and isinstance(query, dict): for key, value in query.items(): self.url += f"&{key}={value}" - except Exception as e: - raise e + except (LighthouseAPIError, req.exceptions.HTTPError): + raise def get(self, headers = None, **kwargs) : try: @@ -26,8 +27,8 @@ def get(self, headers = None, **kwargs) : r = req.get(self.url, headers=headers) r.raise_for_status() return r.json() - except Exception as e: - raise e + except req.exceptions.HTTPError as e: + raise LighthouseAPIError(str(e)) from e def post( self, body=None, headers= None, **kwargs @@ -37,8 +38,8 @@ def post( r = req.post(self.url, data=body, headers=headers) r.raise_for_status() return r.json() - except Exception as e: - raise e + except req.exceptions.HTTPError as e: + raise LighthouseAPIError(str(e)) from e def post_files( self, file, headers = None, **kwargs @@ -54,9 +55,9 @@ def post_files( except Exception: temp = r.text.split("\n") return json.loads(temp[len(temp) - 2]) - except Exception as e: + except req.exceptions.HTTPError as e: utils.close_files_after_upload(files) - raise e + raise LighthouseAPIError(str(e)) from e def post_blob( self, file: BufferedReader, filename: str, headers = None, **kwargs @@ -79,6 +80,6 @@ def post_blob( except Exception: temp = r.text.split("\n") return json.loads(temp[len(temp) - 2]) - except Exception as e: + except req.exceptions.HTTPError as e: file.close() - raise e + raise LighthouseAPIError(str(e)) from e diff --git a/src/lighthouseweb3/functions/deal_status.py b/src/lighthouseweb3/functions/deal_status.py index e4ff62c..b6383a0 100644 --- a/src/lighthouseweb3/functions/deal_status.py +++ b/src/lighthouseweb3/functions/deal_status.py @@ -1,5 +1,6 @@ import requests from .config import Config +from .exceptions import LighthouseAPIError def get_deal_status(cid: str): @@ -9,4 +10,4 @@ def get_deal_status(cid: str): response.raise_for_status() return response.json() except requests.HTTPError as error: - raise Exception(error.response.text) + raise LighthouseAPIError(error.response.text) diff --git a/src/lighthouseweb3/functions/exceptions.py b/src/lighthouseweb3/functions/exceptions.py new file mode 100644 index 0000000..671dfa9 --- /dev/null +++ b/src/lighthouseweb3/functions/exceptions.py @@ -0,0 +1,19 @@ +"""Custom exceptions for Lighthouse Web3 SDK.""" + + +class LighthouseError(Exception): + """Base exception class for all Lighthouse SDK errors.""" + + pass + + +class LighthouseAPIError(LighthouseError): + """Exception raised for HTTP/API errors from Lighthouse services.""" + + pass + + +class LighthouseUploadError(LighthouseError): + """Exception raised for upload-related errors.""" + + pass diff --git a/src/lighthouseweb3/functions/upload.py b/src/lighthouseweb3/functions/upload.py index 652cd8a..79fe6ae 100644 --- a/src/lighthouseweb3/functions/upload.py +++ b/src/lighthouseweb3/functions/upload.py @@ -5,6 +5,7 @@ from .axios import Axios from .utils import is_dir, walk_dir_tree, extract_file_name, NamedBufferedReader from .config import Config +from .exceptions import LighthouseUploadError def upload(source, token: str, tag: str = ""): @@ -52,8 +53,7 @@ def upload(source, token: str, tag: str = ""): "Authorization": f"Bearer {token}", }) return {"data": hashData} except Exception as e: - print(e) - raise e + raise LighthouseUploadError(str(e)) from e def uploadBlob(source: BufferedReader, filename: str, token: str, tag: str = ""): @@ -84,5 +84,4 @@ def uploadBlob(source: BufferedReader, filename: str, token: str, tag: str = "" "Authorization": f"Bearer {token}", }) return {"data": hashData} except Exception as e: - print(e) - raise e + raise LighthouseUploadError(str(e)) from e From 3a5f9619a6b7ca295ef700f86e7c27f18ef9bd8b Mon Sep 17 00:00:00 2001 From: Hiro Date: Tue, 10 Mar 2026 23:06:20 +0000 Subject: [PATCH 2/2] fix(errors): address review feedback for exception flow and cleanup --- src/lighthouseweb3/functions/axios.py | 45 +++++++++------------ src/lighthouseweb3/functions/deal_status.py | 2 +- src/lighthouseweb3/functions/upload.py | 32 +++++++++------ 3 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/lighthouseweb3/functions/axios.py b/src/lighthouseweb3/functions/axios.py index 6d2db3a..72d03c5 100644 --- a/src/lighthouseweb3/functions/axios.py +++ b/src/lighthouseweb3/functions/axios.py @@ -14,14 +14,11 @@ def __init__(self, url: str): self.url = url def parse_url_query(self, query): - try: - if query is not None and isinstance(query, dict): - for key, value in query.items(): - self.url += f"&{key}={value}" - except (LighthouseAPIError, req.exceptions.HTTPError): - raise + if query is not None and isinstance(query, dict): + for key, value in query.items(): + self.url += f"&{key}={value}" - def get(self, headers = None, **kwargs) : + def get(self, headers=None, **kwargs): try: self.parse_url_query(kwargs.get("query", None)) r = req.get(self.url, headers=headers) @@ -30,9 +27,7 @@ def get(self, headers = None, **kwargs) : except req.exceptions.HTTPError as e: raise LighthouseAPIError(str(e)) from e - def post( - self, body=None, headers= None, **kwargs - ): + def post(self, body=None, headers=None, **kwargs): try: self.parse_url_query(kwargs.get("query", None)) r = req.post(self.url, data=body, headers=headers) @@ -41,37 +36,37 @@ def post( except req.exceptions.HTTPError as e: raise LighthouseAPIError(str(e)) from e - def post_files( - self, file, headers = None, **kwargs - ) : + def post_files(self, file, headers=None, **kwargs): + files = None try: self.parse_url_query(kwargs.get("query", None)) files = utils.read_files_for_upload(file) r = req.post(self.url, headers=headers, files=files) r.raise_for_status() - utils.close_files_after_upload(files) try: return r.json() except Exception: temp = r.text.split("\n") return json.loads(temp[len(temp) - 2]) - except req.exceptions.HTTPError as e: - utils.close_files_after_upload(files) + except req.exceptions.RequestException as e: raise LighthouseAPIError(str(e)) from e + finally: + if files is not None: + utils.close_files_after_upload(files) - def post_blob( - self, file: BufferedReader, filename: str, headers = None, **kwargs - ) : + def post_blob(self, file: BufferedReader, filename: str, headers=None, **kwargs): try: self.parse_url_query(kwargs.get("query", None)) - files = [( - "file", + files = [ ( - utils.extract_file_name(filename), - file.read(), - "application/octet-stream", + "file", + ( + utils.extract_file_name(filename), + file.read(), + "application/octet-stream", + ), ), - ),] + ] r = req.post(self.url, headers=headers, files=files) r.raise_for_status() file.close() diff --git a/src/lighthouseweb3/functions/deal_status.py b/src/lighthouseweb3/functions/deal_status.py index b6383a0..726b297 100644 --- a/src/lighthouseweb3/functions/deal_status.py +++ b/src/lighthouseweb3/functions/deal_status.py @@ -10,4 +10,4 @@ def get_deal_status(cid: str): response.raise_for_status() return response.json() except requests.HTTPError as error: - raise LighthouseAPIError(error.response.text) + raise LighthouseAPIError(error.response.text) from error diff --git a/src/lighthouseweb3/functions/upload.py b/src/lighthouseweb3/functions/upload.py index 79fe6ae..33273bd 100644 --- a/src/lighthouseweb3/functions/upload.py +++ b/src/lighthouseweb3/functions/upload.py @@ -5,7 +5,7 @@ from .axios import Axios from .utils import is_dir, walk_dir_tree, extract_file_name, NamedBufferedReader from .config import Config -from .exceptions import LighthouseUploadError +from .exceptions import LighthouseError, LighthouseUploadError def upload(source, token: str, tag: str = ""): @@ -26,7 +26,7 @@ def upload(source, token: str, tag: str = ""): axios = Axios(Config.lighthouse_node + "/api/v0/add") # create list of files to upload - if (isinstance(source, str)): + if isinstance(source, str): file_dict = {} # check if source is a directory @@ -46,17 +46,20 @@ def upload(source, token: str, tag: str = ""): if len(tag): _axios = Axios(Config.lighthouse_api + "/api/user/create_tag") - data = _axios.post({ - "tag": tag, - "cid": hashData.get("Hash") - }, { - "Authorization": f"Bearer {token}", }) + data = _axios.post( + {"tag": tag, "cid": hashData.get("Hash")}, + { + "Authorization": f"Bearer {token}", + }, + ) return {"data": hashData} + except LighthouseError: + raise except Exception as e: raise LighthouseUploadError(str(e)) from e -def uploadBlob(source: BufferedReader, filename: str, token: str, tag: str = ""): +def uploadBlob(source: BufferedReader, filename: str, token: str, tag: str = ""): """ Upload a Buffer or readable Object @params {source}: str, path to file or directory @@ -77,11 +80,14 @@ def uploadBlob(source: BufferedReader, filename: str, token: str, tag: str = "" hashData = axios.post_blob(source, filename, headers) if len(tag): _axios = Axios(Config.lighthouse_api + "/api/user/create_tag") - data = _axios.post({ - "tag": tag, - "cid": hashData.get("Hash") - }, { - "Authorization": f"Bearer {token}", }) + data = _axios.post( + {"tag": tag, "cid": hashData.get("Hash")}, + { + "Authorization": f"Bearer {token}", + }, + ) return {"data": hashData} + except LighthouseError: + raise except Exception as e: raise LighthouseUploadError(str(e)) from e