mirror of
https://github.com/lancedb/lancedb.git
synced 2026-11-13 14:16:54 +00:00
fix(python): improve function failure diagnostics (#4790)
## Summary - Make `AsyncJob.wait(timeout)` and `Job.wait(timeout)` raise a descriptive `TimeoutError` containing the job ID and elapsed timeout. Registry jobs explain that work continues on the server and include the `db.open_job(id).wait()` reattach call. SQL query handles instead say to keep the original handle because query IDs cannot be reopened through the registry jobs API. - Render `JobFailureInfo` and `FunctionErrorRecord` with Python values instead of Rust `Option` wrappers. - Decode and expose the server's `row_address` on `FunctionErrorRecord`, and document how to retry recorded rows with `REFRESH COLUMN ... WHERE _rowaddr IN (...)` before compaction or rewrite. - Warn when an import inside a packaged Function body resolves to undeclared local source. The `udf` documentation explains why arbitrary base-image coverage and distribution-to-import-name mapping cannot be validated reliably by the SDK. `row_address` is optional, so records from older servers still decode with `None`. Rust code that constructs `FunctionErrorRecord` literals must now supply this new field. Part of ENT-3448 and ENT-3442. This consumes the server-side diagnostics from lancedb/sophon#9509 and logical row addresses from lancedb/sophon#9512. ## Validation - Rust `function_errors` remote decoding and legacy-missing-`row_address` tests. - Rust/PyO3 clippy for `lancedb` and `lancedb-python`. - Python extension build, pyright, and ruff. - Targeted Python job, Function packaging, Function error, and job detail tests: 62 passed, plus timeout-handle tests: 3 passed.
This commit is contained in:
+14
-4
@@ -200,10 +200,20 @@ pub struct JobFailureInfo {
|
||||
#[pymethods]
|
||||
impl JobFailureInfo {
|
||||
fn __repr__(&self) -> String {
|
||||
format!(
|
||||
"JobFailureInfo(phase={:?}, message={:?}, retryable={:?})",
|
||||
self.phase, self.message, self.retryable
|
||||
)
|
||||
let phase = self
|
||||
.phase
|
||||
.as_ref()
|
||||
.map_or_else(|| "None".to_string(), |value| format!("{value:?}"));
|
||||
let message = self
|
||||
.message
|
||||
.as_ref()
|
||||
.map_or_else(|| "None".to_string(), |value| format!("{value:?}"));
|
||||
let retryable = match self.retryable {
|
||||
Some(true) => "True",
|
||||
Some(false) => "False",
|
||||
None => "None",
|
||||
};
|
||||
format!("JobFailureInfo(phase={phase}, message={message}, retryable={retryable})")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-3
@@ -596,6 +596,7 @@ pub struct FunctionErrorRecord {
|
||||
pub job_id: String,
|
||||
pub fragment_id: u64,
|
||||
pub row_offset: Option<u32>,
|
||||
pub row_address: Option<u64>,
|
||||
pub column: String,
|
||||
pub function: String,
|
||||
pub function_version: String,
|
||||
@@ -608,12 +609,19 @@ pub struct FunctionErrorRecord {
|
||||
#[pymethods]
|
||||
impl FunctionErrorRecord {
|
||||
pub fn __repr__(&self) -> String {
|
||||
let row_offset = self
|
||||
.row_offset
|
||||
.map_or_else(|| "None".to_string(), |value| value.to_string());
|
||||
let row_address = self
|
||||
.row_address
|
||||
.map_or_else(|| "None".to_string(), |value| value.to_string());
|
||||
format!(
|
||||
"FunctionErrorRecord(job_id={:?}, fragment_id={}, row_offset={:?}, column={:?}, \
|
||||
error_type={:?}, error_message={:?})",
|
||||
"FunctionErrorRecord(job_id={:?}, fragment_id={}, row_offset={}, row_address={}, \
|
||||
column={:?}, error_type={:?}, error_message={:?})",
|
||||
self.job_id,
|
||||
self.fragment_id,
|
||||
self.row_offset,
|
||||
row_offset,
|
||||
row_address,
|
||||
self.column,
|
||||
self.error_type,
|
||||
self.error_message
|
||||
@@ -627,6 +635,7 @@ impl From<lancedb::function::FunctionErrorRecord> for FunctionErrorRecord {
|
||||
job_id: record.job_id,
|
||||
fragment_id: record.fragment_id,
|
||||
row_offset: record.row_offset,
|
||||
row_address: record.row_address,
|
||||
column: record.column,
|
||||
function: record.function,
|
||||
function_version: record.function_version,
|
||||
|
||||
Reference in New Issue
Block a user