Commit 01ab46a4 authored by Jacob's avatar Jacob
Browse files

Added custom exception handling and fixed import errors in scrapers.

parent 3dab43bb
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
from dataclasses import dataclass

@dataclass
class ErrorCodes:
    DB_CONNECTION_FAILED: int = 1001
    DB_TIMEOUT: int = 1002
    DB_INTEGRITY_ERROR: int = 1003

    # Web Scraping Errors
    SCRAPE_CONNECTION_ERROR: int = 2001
    SCRAPE_TIMEOUT: int = 2002
    SCRAPE_PARSING_FAILED: int = 2003
    SCRAPE_DATA_NOT_FOUND: int = 2004

    # Templating Errors
    TEMPLATE_RENDERING_FAILED: int = 3001
    TEMPLATE_NOT_FOUND: int = 3002
    TEMPLATE_SYNTAX_ERROR: int = 3003

    DEFAULT_ERROR: int = 9999
def handle_error():
    error_codes = ErrorCodes()
    print(f"Database connection failed error code: {error_codes.DB_CONNECTION_FAILED}")
 No newline at end of file
+58 −0
Original line number Diff line number Diff line
from common.error_codes import ErrorCodes

class CommonException(Exception):
    def __init__(self, message=None, code=None):
        
        self.code = code if code else ErrorCodes.DEFAULT_ERROR
        self.validate_code(self.code)
        self.message = str(message)
        super().__init__(message)
        
    def __str__(self):
        return f"{self.message} (Error Code: {self.code})"

    @staticmethod
    def validate_code(code: int = None):
        if code and not any(value == code for value in vars(ErrorCodes).values()):
            raise ValueError(f"Invalid error code: {code}")
    
    def __repr__(self):
       return f"{self.__class__.__name__}(message={self.args[0]!r}, code={self.code})"

class ScraperException(CommonException):
    @staticmethod
    def validate_code(code):
        db_codes = {value for name, value in vars(ErrorCodes).items() if name.startswith('SCRAPE_')}
        if code and code not in db_codes:
            raise ValueError(f"Invalid scraper error code: {code}")

class DatabaseException(CommonException):    
    @staticmethod
    def validate_code(code):
        db_codes = {value for name, value in vars(ErrorCodes).items() if name.startswith('DB_')}
        if code and code not in db_codes:
            raise ValueError(f"Invalid database error code: {code}")

class TemplateException(CommonException):    
    @staticmethod
    def validate_code(code):
        db_codes = {value for name, value in vars(ErrorCodes).items() if name.startswith('TEMPLATE_')}
        if code and code not in db_codes:
            raise ValueError(f"Invalid template error code: {code}")

class ParserError(ScraperException):
    def __init__(self, message=None):
        super().__init__(message, 2003)

if __name__ == "__main__":
    try:
        raise TemplateException("Template Connection Failed", 3001)
    except TemplateException as e:
        print(e)
        print(f"{e!r}")
    
    try:
        raise TemplateException("Template Connection Failed", 30001)
    except TemplateException as e:
        print(e)
        print(f"{e!r}")
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""Provide connection methods such as Postgres or sqlalchemy engine."""
import logging
from etl import ce
from common.env import check_environment as ce


def create_uri(logger=logging.getLogger(ce('ETL_LOGGER', 'main'))):
+2 −2
Original line number Diff line number Diff line
@@ -15,8 +15,8 @@
"""
from bs4 import BeautifulSoup as Soup

from scrapers.scraper import Scraper
from scraper.webdriver import WebDriver
from common.scrapers.scraper import Scraper
from common.scrapers.webdriver import WebDriver


class SeleniumScraper(Scraper):
+1 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ from selenium.common.exceptions import StaleElementReferenceException
from selenium.common.exceptions import NoSuchWindowException
from selenium.common.exceptions import TimeoutException
from urllib3.exceptions import HTTPError, ConnectionError
from ei.exceptions import ParserError
from common.exceptions import ParserError
from rich.logging import RichHandler
from rich.traceback import install
install()