(connection: sqlite3.Connection, args: argparse.Namespace)
| 1860 | |
| 1861 | |
| 1862 | def cancel_scan(connection: sqlite3.Connection, args: argparse.Namespace) -> dict[str, Any]: |
| 1863 | scan_id = require_uuid(args.scan_id, "scan-id") |
| 1864 | thread_id = optional_text(args.thread_id, maximum=512) |
| 1865 | if thread_id is None: |
| 1866 | raise SystemExit("thread-id is required.") |
| 1867 | connection.execute("BEGIN IMMEDIATE") |
| 1868 | try: |
| 1869 | timestamp = now() |
| 1870 | scan = require_scan(connection, scan_id) |
| 1871 | workspace = require_workspace(connection, scan["workspace_id"]) |
| 1872 | if workspace["thread_id"] != thread_id: |
| 1873 | raise SystemExit("A scan can only be canceled from its owning Codex thread.") |
| 1874 | if scan["canceled_at"] is not None: |
| 1875 | connection.commit() |
| 1876 | return workspace_state(connection, scan["workspace_id"]) |
| 1877 | if scan["status"] != "running": |
| 1878 | raise SystemExit("Only a running scan can be canceled.") |
| 1879 | updated = connection.execute( |
| 1880 | """ |
| 1881 | UPDATE scans |
| 1882 | SET status = 'failed', canceled_at = ?, completed_at = ?, updated_at = ? |
| 1883 | WHERE id = ? AND status = 'running' |
| 1884 | """, |
| 1885 | (timestamp, timestamp, timestamp, scan["id"]), |
| 1886 | ) |
| 1887 | if updated.rowcount != 1: |
| 1888 | raise SystemExit("Only a running scan can be canceled.") |
| 1889 | progress_updated = connection.execute( |
| 1890 | "UPDATE scan_progress SET updated_at = ? WHERE scan_id = ?", |
| 1891 | (timestamp, scan["id"]), |
| 1892 | ) |
| 1893 | if progress_updated.rowcount != 1: |
| 1894 | raise SystemExit("Codex Security scan progress not found.") |
| 1895 | connection.commit() |
| 1896 | except BaseException: |
| 1897 | connection.rollback() |
| 1898 | raise |
| 1899 | return workspace_state(connection, scan["workspace_id"]) |
| 1900 | |
| 1901 | |
| 1902 | def claim_handoff_delivery( |
no test coverage detected