Skip to content

[UPGRADE] improved error handling by implementing error chaining (- W… #138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ exclude_lines =
raise ImportError
raise baton
baton = ImportError
raise ModuleNotFoundError
baton.module
except subprocess.CalledProcessError
except ..Error
Expand Down Expand Up @@ -56,5 +57,6 @@ partial_branches =
if 'os' not in sys.modules:
if 'os.path' not in sys.modules:
if 'argparse' not in sys.modules:
RuntimeError("SHUTDOWN")


2 changes: 2 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,7 @@ Github:
- README.md

invalid:
- changed-files:
- any-glob-to-any-file:
- .stickler.yml
- .hound.yml
126 changes: 50 additions & 76 deletions multicast/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""Contains the Python Multicast library."""
import sys
import argparse
import unicodedata
import socket
import struct
import abc


# skipcq
__all__ = [
Expand All @@ -29,6 +35,7 @@
"""recv.McastRECV""", """send.McastSAY""", """hear.McastHEAR""",
]


__package__ = """multicast""" # skipcq: PYL-W0622
"""The package of this program.

Expand Down Expand Up @@ -317,58 +324,37 @@
"""


try:
import sys
if sys.__name__ is None:
raise ImportError("FAIL: we could not import os. We're like in the matrix! ABORT.")
except Exception as err:
raise ImportError(err)
if sys.__name__ is None:
raise ModuleNotFoundError(
"FAIL: we could not import sys. We're like in the matrix! ABORT."
) from None


try:
import argparse
if argparse.__name__ is None:
raise ImportError("FAIL: we could not import argparse. ABORT.")
except Exception as err:
raise ImportError(err)
if argparse.__name__ is None:
raise ModuleNotFoundError("FAIL: we could not import argparse. ABORT.") from None


try:
import unicodedata
if unicodedata.__name__ is None:
raise ImportError("FAIL: we could not import unicodedata. ABORT.")
except Exception as err:
raise ImportError(err)
if unicodedata.__name__ is None:
raise ModuleNotFoundError("FAIL: we could not import unicodedata. ABORT.") from None


try:
import socket
if socket.__name__ is None:
raise ImportError("FAIL: we could not import socket. ABORT.")
else: # pragma: no branch
socket.setdefaulttimeout(int(_MCAST_DEFAULT_TTL))
except Exception as err:
raise ImportError(err)
if socket.__name__ is None:
raise ModuleNotFoundError("FAIL: we could not import socket. ABORT.") from None
else: # pragma: no branch
socket.setdefaulttimeout(int(_MCAST_DEFAULT_TTL))


try:
import struct
if struct.__name__ is None:
raise ImportError("FAIL: we could not import struct. ABORT.")
except Exception as err:
raise ImportError(err)
if struct.__name__ is None:
raise ModuleNotFoundError("FAIL: we could not import struct. ABORT.") from None


try:
import abc
if abc.__name__ is None:
raise ImportError("FAIL: we could not import Abstract base class. ABORT.")
except Exception as err:
raise ImportError(err)
if abc.__name__ is None:
raise ModuleNotFoundError("FAIL: we could not import Abstract base class. ABORT.") from None


class mtool(abc.ABC):
"""Class for Multicast tools.
"""
Class for Multicast tools.

Utility class for CLI tools of the Multicast package. setupArgs() and doStep() are
abstract and need to be implemented by subclasses.
Expand All @@ -395,7 +381,8 @@ class mtool(abc.ABC):

@classmethod
def buildArgs(cls, calling_parser_group):
"""Will build the argparse parser.
"""
Will build the argparse parser.

Utility Function to build the argparse parser; see argparse.ArgumentParser for more.
returns argparse.ArgumentParser - the ArgumentParser to use.
Expand Down Expand Up @@ -466,7 +453,8 @@ def buildArgs(cls, calling_parser_group):

@classmethod
def parseArgs(cls, arguments=None):
"""Will attempt to parse the given CLI arguments.
"""
Will attempt to parse the given CLI arguments.

See argparse.ArgumentParser for more.
param str - arguments - the array of arguments to parse. Usually sys.argv[1:]
Expand Down Expand Up @@ -520,7 +508,8 @@ def parseArgs(cls, arguments=None):

@classmethod
def checkToolArgs(cls, args):
"""Will handle the None case for arguments.
"""
Will handle the None case for arguments.

Used as a helper function.

Expand Down Expand Up @@ -566,7 +555,8 @@ def checkToolArgs(cls, args):
return [None] if args is None else args

def __call__(self, *args, **kwargs):
"""Call self as a function.
"""
Call self as a function.

Default implementation simply calls the abstract function doStep
and passes the given positional arguments, thus key-word arguments
Expand All @@ -589,14 +579,10 @@ def doStep(self, *args): # pragma: no cover
pass # skipcq - abstract method


try:
if 'multicast.skt' not in sys.modules:
from . import skt as skt # pylint: disable=cyclic-import - skipcq: PYL-R0401, PYL-C0414
else: # pragma: no branch
skt = sys.modules["""multicast.skt"""]
except Exception as importErr:
del importErr # skipcq - cleanup any error leaks early
import multicast.skt as skt # pylint: disable=cyclic-import - skipcq: PYL-R0401
if 'multicast.skt' not in sys.modules:
from . import skt as skt # pylint: disable=cyclic-import - skipcq: PYL-R0401, PYL-C0414
else: # pragma: no branch
skt = sys.modules["""multicast.skt"""]


genSocket = skt.genSocket
Expand All @@ -605,34 +591,22 @@ def doStep(self, *args): # pragma: no cover
endSocket = skt.endSocket


try:
if 'multicast.recv' not in sys.modules:
from . import recv as recv # pylint: disable=cyclic-import - skipcq: PYL-R0401
else: # pragma: no branch
recv = sys.modules["""multicast.recv"""]
except Exception as importErr:
del importErr # skipcq - cleanup any error leaks early
import multicast.recv as recv # pylint: disable=cyclic-import - skipcq: PYL-R0401
if 'multicast.recv' not in sys.modules:
from . import recv as recv # pylint: disable=cyclic-import - skipcq: PYL-R0401
else: # pragma: no branch
recv = sys.modules["""multicast.recv"""]


try:
if 'multicast.send' not in sys.modules:
from . import send as send # pylint: disable=cyclic-import - skipcq: PYL-R0401
else: # pragma: no branch
send = sys.modules["""multicast.send"""]
except Exception as importErr:
del importErr # skipcq - cleanup any error leaks early
import multicast.send as send # pylint: disable=cyclic-import - skipcq: PYL-R0401
if 'multicast.send' not in sys.modules:
from . import send as send # pylint: disable=cyclic-import - skipcq: PYL-R0401
else: # pragma: no branch
send = sys.modules["""multicast.send"""]


try:
if 'multicast.hear' not in sys.modules:
from . import hear as hear # pylint: disable=cyclic-import - skipcq: PYL-R0401
else: # pragma: no branch
hear = sys.modules["""multicast.hear"""]
except Exception as importErr:
del importErr # skipcq - cleanup any error leaks early
import multicast.hear as hear # pylint: disable=cyclic-import - skipcq: PYL-R0401
if 'multicast.hear' not in sys.modules:
from . import hear as hear # pylint: disable=cyclic-import - skipcq: PYL-R0401
else: # pragma: no branch
hear = sys.modules["""multicast.hear"""]


try:
Expand Down
92 changes: 32 additions & 60 deletions multicast/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,79 +77,51 @@

try:
from . import sys as _sys
except Exception:
except Exception as impErr:
# Throw more relevant Error
raise ImportError(str("[CWE-440] Error Importing Python"))
raise ImportError(str("[CWE-440] Error Importing Python")) from impErr


try:
if 'multicast.__version__' not in _sys.modules:
from . import __version__ as __version__ # skipcq: PYL-C0414
else: # pragma: no branch
__version__ = _sys.modules["""multicast.__version__"""]
except Exception as importErr:
del importErr # skipcq - cleanup any error leaks early
import multicast.__version__ as __version__ # noqa. skipcq - used by --version argument.
if 'multicast.__version__' not in _sys.modules:
from . import __version__ as __version__ # skipcq: PYL-C0414
else: # pragma: no branch
__version__ = _sys.modules["""multicast.__version__"""]


try:
if 'multicast._MCAST_DEFAULT_PORT' not in _sys.modules:
from . import _MCAST_DEFAULT_PORT as _MCAST_DEFAULT_PORT # skipcq: PYL-C0414
else: # pragma: no branch
_MCAST_DEFAULT_PORT = _sys.modules["""multicast._MCAST_DEFAULT_PORT"""]
except Exception as importErr:
del importErr # skipcq - cleanup any error leaks early
import multicast._MCAST_DEFAULT_PORT as _MCAST_DEFAULT_PORT # skipcq - used by port argument.
if 'multicast._MCAST_DEFAULT_PORT' not in _sys.modules:
from . import _MCAST_DEFAULT_PORT as _MCAST_DEFAULT_PORT # skipcq: PYL-C0414
else: # pragma: no branch
_MCAST_DEFAULT_PORT = _sys.modules["""multicast._MCAST_DEFAULT_PORT"""]


try:
if 'multicast._MCAST_DEFAULT_GROUP' not in _sys.modules:
from . import _MCAST_DEFAULT_GROUP as _MCAST_DEFAULT_GROUP # skipcq: PYL-C0414
else: # pragma: no branch
_MCAST_DEFAULT_GROUP = _sys.modules["""multicast._MCAST_DEFAULT_GROUP"""]
except Exception as importErr:
del importErr # skipcq - cleanup any error leaks early
import multicast._MCAST_DEFAULT_GROUP as _MCAST_DEFAULT_GROUP # skipcq - used by group arg.
if 'multicast._MCAST_DEFAULT_GROUP' not in _sys.modules:
from . import _MCAST_DEFAULT_GROUP as _MCAST_DEFAULT_GROUP # skipcq: PYL-C0414
else: # pragma: no branch
_MCAST_DEFAULT_GROUP = _sys.modules["""multicast._MCAST_DEFAULT_GROUP"""]


try:
if 'multicast.mtool' not in _sys.modules:
from . import mtool as mtool # skipcq: PYL-C0414
else: # pragma: no branch
mtool = _sys.modules["""multicast.mtool"""]
except Exception as importErr:
del importErr # skipcq - cleanup any error leaks early
import multicast.mtool as mtool # noqa - used by all arguments' CMD (sub-command).
if 'multicast.mtool' not in _sys.modules:
from . import mtool as mtool # skipcq: PYL-C0414
else: # pragma: no branch
mtool = _sys.modules["""multicast.mtool"""]


try:
if 'multicast.recv' not in _sys.modules:
from . import recv as recv # pylint: disable=useless-import-alias - skipcq: PYL-C0414
else: # pragma: no branch
recv = _sys.modules["""multicast.recv"""]
except Exception as importErr:
del importErr # skipcq - cleanup any error leaks early
import multicast.recv as recv # pylint: disable=useless-import-alias - skipcq: PYL-C0414
if 'multicast.recv' not in _sys.modules:
from . import recv as recv # pylint: disable=useless-import-alias - skipcq: PYL-C0414
else: # pragma: no branch
recv = _sys.modules["""multicast.recv"""]


try:
if 'multicast.send' not in _sys.modules:
from . import send as send # pylint: disable=useless-import-alias - skipcq: PYL-C0414
else: # pragma: no branch
send = _sys.modules["""multicast.send"""]
except Exception as importErr:
del importErr # skipcq - cleanup any error leaks early
import multicast.send as send # pylint: disable=useless-import-alias - skipcq: PYL-C0414
if 'multicast.send' not in _sys.modules:
from . import send as send # pylint: disable=useless-import-alias - skipcq: PYL-C0414
else: # pragma: no branch
send = _sys.modules["""multicast.send"""]


try:
if 'multicast.hear' not in _sys.modules:
from . import hear as hear # pylint: disable=useless-import-alias - skipcq: PYL-C0414
else: # pragma: no branch
hear = _sys.modules["""multicast.hear"""]
except Exception as importErr:
del importErr # skipcq - cleanup any error leaks early
import multicast.hear as hear # pylint: disable=useless-import-alias - skipcq: PYL-C0414
if 'multicast.hear' not in _sys.modules:
from . import hear as hear # pylint: disable=useless-import-alias - skipcq: PYL-C0414
else: # pragma: no branch
hear = _sys.modules["""multicast.hear"""]


class McastNope(mtool):
Expand Down Expand Up @@ -462,8 +434,8 @@ def doStep(self, *args, **kwargs):
This method selects either the `McastHEAR` or `McastRECV` class based on the daemon
dispatch flag and executes the corresponding step.

The RECV (via McastRECV) is the primitive sub-command to recieve a single multicas hunk.
The HEAR (via McastHEAR) is equivilant to running RECV in a loop to continually recive
The RECV (via McastRECV) is the primitive sub-command to receive a single multicas hunk.
The HEAR (via McastHEAR) is equivalent to running RECV in a loop to continually receive
multiple hunks. Most use-case will probably want to use HEAR instead of RECV.

Args:
Expand Down
Loading
Loading