autowisp.exceptions module

Class Inheritance Diagram

Inheritance diagram of AutoWISPError, BUIError, BadImageError, CalibrationError, CatalogError, Component, ConfigurationError, ConvergenceError, CreateLightCurvesError, DatabaseError, DependencyResolutionError, DetrendingStatError, EPDError, Enum, FileKind, FindStarsError, FitMagnitudesError, FitPSFMapError, FitStarShapeError, FormValidationError, FrozenRow, HDF5LayoutError, ImageMismatchError, MasterSelectionError, MeasurePhotometryError, NoSourcesFoundError, OutsideImageError, Path, PhotrefBindingError, PipelineError, ProjectStateError, RelatedFile, ResourceError, SolveAstrometryError, StackToMasterError, StepError, TFAError, ViewError, WorkerCrashedError, datetime, timezone

The AutoWISP exception hierarchy.

Every exception AutoWISP raises on purpose derives from AutoWISPError, which carries enough context (the affected artifact(s), the pipeline run, the worker that raised it, a short user-facing message, and an arbitrary details dict) to power CLI messages, BUI surfacing, and post-mortem debugging from a single source of truth. See error_handling_plan.md for the full design.

This module imports only FrozenRow from the database package (itself dependency-free), so the hierarchy stays free of a hard SQLAlchemy dependency.

exception autowisp.exceptions.AutoWISPError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: Exception

Base class for every AutoWISP-raised exception.

Every concrete subclass selects a Component.

component

Set on each subclass; verified by tests.

Type:

Component

related_files

The RelatedFile entries this error is about.

Type:

tuple

pipeline_run

Snapshot of the PipelineRun row (see FrozenRow), set by the pipeline driver when it wraps a step’s exception, or by wisp-* entry points. None for runs with no DB row.

Type:

FrozenRow or None

crashed

When the failure surfaced, filled in by the top-level handler.

Type:

datetime or None

subprocess_id

PID of the multiprocessing worker that raised, when the exception travelled out of a Pool; None for errors raised in the main process.

Type:

int or None

user_message

Short, free of jargon, suitable for the BUI.

Type:

str

details

Arbitrary key/value pairs giving extra context about the failure (e.g. shape mismatches, expected/actual values, parsed config). Useful to both users and developers.

Type:

dict

__init__(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Store the context attributes (see class Attributes).

__reduce__()[source]

Pickle by restoring __dict__ rather than re-running __init__.

Subclasses (e.g. StepError) accept keyword-only arguments and carry context attributes that are not part of self.args, so the default exception unpickler – which calls cls(*self.args) – would both drop those fields and (for required kwargs) raise TypeError. Reconstructing through __new__ + __dict__ keeps every field intact and lets the exception travel back out of a multiprocessing worker faithfully.

Returns:

(callable, args) per the pickle protocol.

Return type:

tuple

component: Component
stamp_subprocess() None[source]

Record the current PID as the raising sub-process.

Called by the worker before re-raising out of a multiprocessing Pool. Idempotent: a value already set in a deeper worker wins.

Returns:

None

to_detail_dict() dict[source]

Return the heavy, non-column fields for the error sidecar.

Complements the queryable columns of the Error row: everything here is what does not live inline on the row – the full technical message, the complete related-file list (a superset of the artifact FKs), the arbitrary details dict, and the formatted traceback (__cause__ chain included). The result may still contain numpy/Path/etc. inside details; serialize it with json.dump(..., default=sanitize_for_json).

Returns:

The sidecar payload (see error_handling_plan.md).

Return type:

dict

with_pipeline_run(run: FrozenRow | None, *, crashed: datetime | None = None) AutoWISPError[source]

Attach a FrozenRow snapshot of the PipelineRun.

Parameters:
  • run (FrozenRow or None) – Row snapshot to attach. Built by snapshot_row (parent) or from config primitives (worker), so host/started are already populated; nothing is reconstructed here.

  • crashed (datetime or None) – Failure time; defaults to now if not already set on the exception.

Returns:

self, so it can be used inline before

re-raising.

Return type:

AutoWISPError

exception autowisp.exceptions.BUIError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: AutoWISPError

Failure in the Django views/forms/templates of the BUI.

component: Component = 'bui'
exception autowisp.exceptions.BadImageError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

An image does not look like it is expected to.

exception autowisp.exceptions.CalibrationError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Failure in the calibrate step.

exception autowisp.exceptions.CatalogError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

A problem with the reference catalog (query or coverage/consistency).

A cross-cutting StepError – catalog trouble is not specific to one stage: a live Gaia query can exhaust its retries, and a cached catalog can fail to cover the frames or mismatch the required epoch / magnitude range / field of view during solve_astrometry, find_stars, fit_star_shape, etc. Raised as one catchable type across all of them (step_name is stamped from the ambient context), so callers can except CatalogError regardless of which step triggered it.

class autowisp.exceptions.Component(value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]

Bases: str, Enum

Inheritance diagram of autowisp.exceptions.Component

Which broad part of AutoWISP an error belongs to.

BUI = 'bui'
PIPELINE = 'pipeline'
STEP = 'step'
exception autowisp.exceptions.ConfigurationError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: PipelineError

Invalid or inconsistent pipeline configuration.

exception autowisp.exceptions.ConvergenceError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Some iterative procedure failed to converge.

exception autowisp.exceptions.CreateLightCurvesError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Failure in the create_lightcurves step.

exception autowisp.exceptions.DatabaseError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: PipelineError

Failure interacting with the pipeline database.

exception autowisp.exceptions.DependencyResolutionError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: PipelineError

Failure resolving processing-step dependencies.

exception autowisp.exceptions.DetrendingStatError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Failure computing detrending statistics.

exception autowisp.exceptions.EPDError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Failure in the EPD detrending step.

class autowisp.exceptions.FileKind(value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None)[source]

Bases: str, Enum

Inheritance diagram of autowisp.exceptions.FileKind

The sort of file a RelatedFile points at.

CALIBRATED_IMAGE = 'calibrated_image'
CATALOG = 'catalog'
CONFIG = 'config'
DR_FILE = 'dr_file'
LIGHTCURVE = 'lightcurve'
MASTER_BIAS = 'master_bias'
MASTER_DARK = 'master_dark'
MASTER_FLAT = 'master_flat'
MASTER_PHOTREF = 'master_photref'
OTHER = 'other'
OUTPUT = 'output'
RAW_IMAGE = 'raw_image'
exception autowisp.exceptions.FindStarsError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Failure in the find_stars step.

exception autowisp.exceptions.FitMagnitudesError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Failure in the fit_magnitudes step.

exception autowisp.exceptions.FitPSFMapError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Failure in the fit_source_extracted_psf_map step.

exception autowisp.exceptions.FitStarShapeError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Failure in the fit_star_shape step.

exception autowisp.exceptions.FormValidationError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: BUIError

A BUI form failed validation in a way worth recording.

exception autowisp.exceptions.HDF5LayoutError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: PipelineError

Error caused by invalid specification of HDF5 layout.

exception autowisp.exceptions.ImageMismatchError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Attempt to combine incompatible images in some way.

exception autowisp.exceptions.MasterSelectionError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: PipelineError

Failure selecting the master frame(s) for an image.

exception autowisp.exceptions.MeasurePhotometryError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Failure in the measure_aperture_photometry step.

exception autowisp.exceptions.NoSourcesFoundError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: FindStarsError

Source extraction completed but found no sources in a frame.

Distinct from a generic FindStarsError so the step can mark just that frame as failed and carry on (a clouded or badly defocused frame is not a reason to abort the run), while every other find_stars failure still propagates.

exception autowisp.exceptions.OutsideImageError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: CalibrationError

Attempt to access image data outside the bounds of the image.

Raised only in the calibration path, so it specializes CalibrationError rather than the generic StepError.

exception autowisp.exceptions.PhotrefBindingError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: PipelineError

Failure binding a photometric reference.

exception autowisp.exceptions.PipelineError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: AutoWISPError

Failure in the orchestration layer (not “the algorithm”).

component: Component = 'pipeline'
exception autowisp.exceptions.ProjectStateError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: BUIError

The BUI project is in a state that blocks the requested action.

class autowisp.exceptions.RelatedFile(kind: FileKind, path: Path, role: str = '')[source]

Bases: object

Inheritance diagram of autowisp.exceptions.RelatedFile

A file the error is about (input, output, or intermediate).

kind

What sort of file this is.

Type:

FileKind

path

Location of the file.

Type:

Path

role

How the file relates to the failure, e.g. "input" / "intermediate" / "expected_output".

Type:

str

__post_init__()[source]

Coerce path to a Path so call sites never see a raw str.

kind: FileKind
path: Path
role: str = ''
exception autowisp.exceptions.ResourceError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: PipelineError

Insufficient disk / memory / CPU to continue.

exception autowisp.exceptions.SolveAstrometryError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Failure in the solve_astrometry step.

exception autowisp.exceptions.StackToMasterError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Failure stacking calibration frames into a master.

exception autowisp.exceptions.StepError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: AutoWISPError

Failure inside a processing step.

step_name

Name of the step that failed. May be None at raise time and filled in from the ambient context by the capture layer.

Type:

str or None

component: Component = 'step'
exception autowisp.exceptions.TFAError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

Failure in the TFA detrending step.

exception autowisp.exceptions.ViewError(message: str, *, related_files: Sequence[RelatedFile] = (), pipeline_run: FrozenRow | None = None, crashed: datetime | None = None, subprocess_id: int | None = None, user_message: str | None = None, details: dict | None = None)[source]

Bases: BUIError

Failure rendering or handling a BUI view.

exception autowisp.exceptions.WorkerCrashedError(message: str, *, step_name: str | None = None, **kwargs)[source]

Bases: StepError

A multiprocessing worker died without preserving its exception.

Re-raise wrapper used when a worker dies in a way that does not propagate the original exception (segfault, OOM-killer, os._exit).

A StepError (component step): although the parent synthesises it – the worker cannot describe its own death – the failure is in the algorithm running inside a step, and the error belongs to that step. It is a single generic class rather than one of the per-stage subclasses because the parent has only the ambient step name, not the failing step’s exception type. That step_name – stamped from the ambient context like any other StepError – is what lets crash-report log-collection resolve the run/step whose logs to gather (see autowisp.error_context._worker_crashed()).

autowisp.exceptions._rebuild_autowisp_error(cls, args, state)[source]

Reconstruct an AutoWISPError subclass for unpickling.

Bypasses __init__ (so keyword-only arguments on subclasses do not block unpickling) and restores both BaseException.args (where the message lives, in C-level storage outside __dict__) and the instance __dict__ directly. See AutoWISPError.__reduce__().

Parameters:
  • cls (type) – The concrete exception class to rebuild.

  • args (tuple) – The original self.args (the message).

  • state (dict) – The instance __dict__ captured at pickle time.

Returns:

The reconstructed exception.

Return type:

AutoWISPError

autowisp.exceptions.collect_environment(packages=('autowisp', 'astrowisp', 'numpy', 'scipy', 'pandas', 'sqlalchemy', 'astropy'))[source]

Platform + key package versions of the current process.

Recorded into the error sidecar at crash time (by error_persistence) so a report reflects the environment that actually produced the failure – immune to the report being built later, after packages were upgraded. Report-time provenance records the same shape for the machine building the report, so comparing the two reveals drift. Never raises.

Parameters:

packages (iterable) – Distribution names whose versions to record (the runtime stack whose combination determines whether a crash reproduces); those not installed are omitted.

Returns:

platform / python_version / packages.

Return type:

dict

autowisp.exceptions.collect_resource_snapshot()[source]

Best-effort machine-memory snapshot (bytes), for diagnosing OOM.

System memory pressure is the tell for an OOM / macOS-jetsam kill: a SIGKILL with no native traceback plus a nearly-full machine points at memory, not a crash. The dead worker’s own peak RSS is gone by the time the parent looks, but the machine’s RAM ceiling and the parent’s RSS are strong signal. Cross-OS via psutil (a hard dependency).

Never raises – a failure yields a partial or empty dict rather than turning the recording of one error into a second error.

Returns:

Any of ram_total / ram_available (bytes),

ram_percent_used (percent), process_rss (bytes).

Return type:

dict

autowisp.exceptions.get_hostname()[source]

This machine’s name, recorded consistently across the pipeline.

A single source so the run host (PipelineRun.host) and the report host (autowisp.crash_report.collect_provenance()) agree – otherwise socket.getfqdn() in one place and socket.gethostname() in another make one box look like two. gethostname is preferred: it is fast and returns the clean local name rather than a reverse-DNS *.in-addr.arpa form on a loopback-only host.

autowisp.exceptions.sanitize_for_json(obj, max_inline_array_size=64)[source]

Coerce an otherwise-unserializable object to a JSON-friendly form.

Intended as the default= argument to json.dump()/json.dumps when writing the error sidecar: details may carry numpy scalars/arrays, Path, datetime, sets, and arbitrary objects. This is total – it never raises, so a pathological value can never turn recording an error into a second error; the last resort is repr().

Use directly (default=sanitize_for_json) for the default threshold, or default=functools.partial(sanitize_for_json, max_inline_array_size=N) to override it.

Parameters:
  • obj – The value json could not serialize natively.

  • max_inline_array_size (int) – ndarrays with at most this many elements are dumped in full; larger ones are summarized so a stray full-frame array cannot write hundreds of MB.

Returns:

A JSON-serializable stand-in for obj.