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:

  1. err: expected to be an Exception instance.

  2. error_msg: optional high-level message to expose to callers.

  3. silent: when True, only logs a warning and does not raise.

  4. func_name: currently unused in implementation.

Behavior Matrix#

Case 1: silent=True#

  1. Logs warning with error_msg.

  2. Returns without raising.

Case 2: silent=False, error_msg is None, err is Exception#

  1. Logs the original exception type and message.

  2. Re-raises the same exception object.

Case 3: silent=False, error_msg is None, err is not Exception#

  1. Logs invalid usage.

  2. Raises RuntimeError.

Case 4: silent=False, error_msg provided, err is Exception#

  1. Logs wrapped context plus cause.

  2. Raises RuntimeError(error_msg) with chained cause (raise ... from err).

Case 5: silent=False, error_msg provided, err is not Exception#

  1. Logs invalid usage.

  2. Raises RuntimeError with combined message.

Why This Pattern Is Used#

This project uses handle_error to:

  1. Keep error messages consistent across modules.

  2. Preserve root cause while exposing cleaner user-facing messages.

  3. Avoid silent failures in most code paths.

You can see usage in:

  1. Traffic managers (plestylib/traffic).

  2. Base device classes (plestylib/device/base_*).

  3. Solvers (plestylib/solver).

  4. 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)

Common Pitfalls#

  1. Passing strings instead of Exception objects as err.

  2. Using silent=True too broadly and hiding critical failures.

  3. Expecting func_name to appear in output (it is currently unused).

  4. Assuming wrapped errors keep original exception type when error_msg is provided.

Integration Guidance#

Use this pattern by layer:

  1. Traffic manager: wrap connection/read/write failures with transport-specific context.

  2. Solver: wrap parse/serialization failures with operation context.

  3. Device class: expose operation-level context such as command key and device identity.

  4. Param/func system: raise validation errors early, before sending traffic.