Error Handling#
PlestyLib centralizes most runtime error behavior through handle_error in plestylib.utils.error_utils.
This utility standardizes logging and exception raising across device, traffic, and solver layers.
Core Utility#
Signature:
handle_error(err, error_msg=None, silent=False, func_name="Unknown Function")
Parameters:
err: expected to be an Exception instance.error_msg: optional high-level message to expose to callers.silent: whenTrue, only logs a warning and does not raise.func_name: currently unused in implementation.
Behavior Matrix#
Case 1: silent=True#
Logs warning with
error_msg.Returns without raising.
Case 2: silent=False, error_msg is None, err is Exception#
Logs the original exception type and message.
Re-raises the same exception object.
Case 3: silent=False, error_msg is None, err is not Exception#
Logs invalid usage.
Raises
RuntimeError.
Case 4: silent=False, error_msg provided, err is Exception#
Logs wrapped context plus cause.
Raises
RuntimeError(error_msg)with chained cause (raise ... from err).
Case 5: silent=False, error_msg provided, err is not Exception#
Logs invalid usage.
Raises
RuntimeErrorwith combined message.
Why This Pattern Is Used#
This project uses handle_error to:
Keep error messages consistent across modules.
Preserve root cause while exposing cleaner user-facing messages.
Avoid silent failures in most code paths.
You can see usage in:
Traffic managers (
plestylib/traffic).Base device classes (
plestylib/device/base_*).Solvers (
plestylib/solver).Parameter system (
plestylib/device/params.py).
Usage Examples#
Re-raise the original exception#
from plestylib.utils.error_utils import handle_error
try:
risky_call()
except Exception as e:
handle_error(e)
Raise a contextual runtime error with chained cause#
from plestylib.utils.error_utils import handle_error
try:
device.connect()
except Exception as e:
handle_error(e, "Failed to connect to instrument")
Warning-only mode (rare)#
from plestylib.utils.error_utils import handle_error
try:
optional_background_task()
except Exception as e:
handle_error(e, "Background task failed", silent=True)
Recommended Practices#
Pass real Exception instances as
err.Provide
error_msgwhen you want a stable caller-facing message.Use warning-only mode (
silent=True) only for explicitly non-critical flows.Prefer fail-fast behavior in device I/O, protocol parsing, and parameter validation.
Preserve context by raising with chained causes when wrapping low-level errors.
Common Pitfalls#
Passing strings instead of Exception objects as
err.Using
silent=Truetoo broadly and hiding critical failures.Expecting
func_nameto appear in output (it is currently unused).Assuming wrapped errors keep original exception type when
error_msgis provided.
Integration Guidance#
Use this pattern by layer:
Traffic manager: wrap connection/read/write failures with transport-specific context.
Solver: wrap parse/serialization failures with operation context.
Device class: expose operation-level context such as command key and device identity.
Param/func system: raise validation errors early, before sending traffic.