From 094d060b57dfff8f7d41e6fc1dce33cb7fdde95b Mon Sep 17 00:00:00 2001 From: mengw15 <125719918+mengw15@users.noreply.github.com> Date: Fri, 15 May 2026 21:20:56 -0700 Subject: [PATCH] fix: preserve original error in IcebergIterator._seek_to_usable_file The bare `raise Exception` (no args, no `from`) constructed a fresh empty exception, discarding the underlying error type, message, and traceback. Callers doing `except Exception as e: log.error(str(e))` saw only an empty string instead of the real diagnostic (catalog auth failure, S3 IO error, manifest corruption, etc.). The `print` also bypassed the project logger. Replace with a re-raise of the original exception and route the message through loguru. Closes #5091. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../core/storage/iceberg/iceberg_document.py | 7 ++-- .../test_iceberg_iterator_error_paths.py | 37 +++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 amber/src/test/python/core/storage/iceberg/test_iceberg_iterator_error_paths.py diff --git a/amber/src/main/python/core/storage/iceberg/iceberg_document.py b/amber/src/main/python/core/storage/iceberg/iceberg_document.py index 997ab9b5b70..7a5beda916d 100644 --- a/amber/src/main/python/core/storage/iceberg/iceberg_document.py +++ b/amber/src/main/python/core/storage/iceberg/iceberg_document.py @@ -17,6 +17,7 @@ import pyarrow as pa from itertools import islice +from loguru import logger from pyiceberg.catalog import Catalog from pyiceberg.schema import Schema from pyiceberg.table import Table, FileScanTask @@ -211,9 +212,9 @@ def _seek_to_usable_file(self) -> Iterator[FileScanTask]: self.num_of_skipped_records += record_count continue yield task - except Exception: - print("Could not read iceberg table:\n") - raise Exception + except Exception as err: + logger.exception(err) + raise else: return iter([]) diff --git a/amber/src/test/python/core/storage/iceberg/test_iceberg_iterator_error_paths.py b/amber/src/test/python/core/storage/iceberg/test_iceberg_iterator_error_paths.py new file mode 100644 index 00000000000..d724ac31d53 --- /dev/null +++ b/amber/src/test/python/core/storage/iceberg/test_iceberg_iterator_error_paths.py @@ -0,0 +1,37 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +from unittest.mock import Mock, patch + +import pytest + +from core.storage.iceberg import iceberg_document +from core.storage.iceberg.iceberg_document import IcebergIterator + + +def test_seek_to_usable_file_preserves_original_error(): + failing_table = Mock() + failing_table.refresh.side_effect = RuntimeError( + "Catalog auth failure: token expired" + ) + + with patch.object( + iceberg_document, "load_table_metadata", return_value=failing_table + ): + it = IcebergIterator(0, None, None, "ns", "tbl", None, None) + with pytest.raises(RuntimeError, match="Catalog auth failure"): + next(it)