autowisp.error_persistence module

Class Inheritance Diagram

Inheritance diagram of Component, Error, Image, MasterFile, datetime, timedelta, timezone

Persist AutoWISP errors as a queryable row plus a JSON sidecar.

Each persisted error becomes a small, queryable Error row (the fields list views and aggregate queries need) plus a per-error JSON sidecar holding the heavy remainder (full message, complete related-file list, details, traceback). The split keeps the SQLite file small while still capturing rich context.

Two hard rules: persisting an error never raises (recording a failure must not cause a second one), and only the main process writes – a worker’s exception is already marshalled back to the main process before the top-level handler calls persist_error().

autowisp.error_persistence._build_error_row(exc, db_session)[source]

Build the inline Error row (without sidecar_path).

autowisp.error_persistence._error_bucket(exc)[source]

Return the sidecar sub-directory name for exc.

Bucketing by run keeps directories small and makes “drop everything from run 88” a single rmtree. Errors with no run go to bui or cli by component.

autowisp.error_persistence._iter_sidecar_files(errors_dir)[source]

Yield (absolute_path, basename) for every file under errors_dir.

autowisp.error_persistence._resolve_artifact_fks(related_files, db_session)[source]

Map related files to known artifact rows (best-effort).

Resolves only artifacts that are genuine database rows with a stored path: a related file whose path matches Image.raw_fname gives the image, one matching MasterFile.filename gives the master. DR files, calibrated images, and lightcurves are HDF5 files with no row, so they are not linked here – they remain in the sidecar’s related-file list by path.

Parameters:
  • related_files (Sequence[RelatedFile]) – The error’s related files.

  • db_session – Active database session.

Returns:

(image_id, master_file_id), each None if no

related file maps to such a row.

Return type:

tuple

autowisp.error_persistence._row_age(row)[source]

The time an error row is dated by: its crash time, else write time.

Remove path if present, swallowing OS errors. Returns success.

autowisp.error_persistence._write_sidecar(exc, error_id, bucket, *, gzip_threshold=65536)[source]

Atomically write the sidecar JSON and return its relative path.

The payload is written to a .tmp file and then os.replace``d into place, so a reader never sees a half-written file. Payloads above ``gzip_threshold bytes are gzipped (the stored filename records which).

Parameters:
  • exc (AutoWISPError) – The error to serialize.

  • error_id (int) – The row id; names the file.

  • bucket (str) – The sub-directory (see _error_bucket()).

  • gzip_threshold (int) – Byte size above which the payload is gzipped.

Returns:

The sidecar path relative to the project home.

Return type:

str

autowisp.error_persistence.cleanup_errors(*, older_than=None)[source]

Prune persisted errors: aged rows, orphan files, dangling rows.

Three passes, all best-effort:

  1. Aged rows – when older_than is given, delete every Error row dated (crash time, else row write time) before the cutoff, along with its sidecar.

  2. Dangling rows – a surviving row whose sidecar_path points at a missing file has the path cleared (the row stays valid as inline-only).

  3. Orphan files – any file under <project_home>/errors that is not the sidecar of a surviving row (leftovers from write-path crashes, including .tmp files) is removed.

Parameters:

older_than (timedelta or None) – Retention cutoff; None skips the aged-row pass and only sweeps orphans/dangling rows.

Returns:

Counts ``{“removed_rows”, “removed_files”,

”cleared_dangling”}``.

Return type:

dict

autowisp.error_persistence.cleanup_main()[source]

CLI entry point for wisp-cleanup-errors.

autowisp.error_persistence.delete_all_error_sidecars(db_session=None)[source]

Delete the sidecar file of every recorded error.

Used when a project is deleted: removes exactly the files error persistence wrote (one per Error row), leaving any unrelated files under the errors directory untouched. The emptied directories are cleaned up by the caller’s directory pruning.

Parameters:

db_session – Optional active session; one is opened if omitted.

Returns:

None

autowisp.error_persistence.delete_error(error_id, db_session=None)[source]

Delete an error record entirely: its row and its sidecar file.

A no-op if the row does not exist. Safe to call from a user action.

Parameters:
  • error_id (int) – The id of the error to delete.

  • db_session – Optional active session; one is opened if omitted.

Returns:

True if a row was deleted, False if none was found.

Return type:

bool

autowisp.error_persistence.load_sidecar(error_row)[source]

Return the parsed sidecar detail for an Error row, or None.

The lazy read path: list views use only the inline columns; this is called only when drilling into one error. A missing or unreadable sidecar degrades to None (“detail unavailable”), never raises.

Parameters:

error_row (Error) – The row whose sidecar to load.

Returns:

The parsed sidecar payload, or None.

Return type:

dict or None

autowisp.error_persistence.parse_duration(text)[source]

Parse a compact duration like 30d / 12h / 2w to timedelta.

Parameters:

text (str) – An integer followed by a unit (s/m/h/ d/w).

Returns:

The parsed duration.

Return type:

timedelta

Raises:

ValueError – If text is not a recognized duration.

autowisp.error_persistence.persist_error(exc, *, sidecar_gzip_threshold=65536)[source]

Persist exc as an Error row plus a JSON sidecar.

Best-effort and never raises. The row is committed first, so it survives even if the sidecar write later fails (its sidecar_path then stays NULL and readers treat it as “inline fields only”). Only the parent process should call this.

Parameters:
  • exc (AutoWISPError) – The (already-stamped) error to record.

  • sidecar_gzip_threshold (int) – Byte size above which the sidecar payload is gzipped.

Returns:

The new Error.id, or None if even the row

insert failed.

Return type:

int or None