fix(api): attach exc_info=True to logger.warning sites that drop the traceback (#41068)

This commit is contained in:
mesrop2008
2026-08-21 11:20:42 +00:00
committed by GitHub
parent d6147456e3
commit 23150c2319
16 changed files with 63 additions and 37 deletions
@@ -167,8 +167,8 @@ class ApolloClient:
old_value = old_kv.get(key)
if old_value is None:
self._change_listener("add", namespace, key, new_value)
except BaseException as e:
logger.warning(str(e))
except BaseException:
logger.warning("Apollo config change listener failed", exc_info=True)
def _path_checker(self) -> None:
if not os.path.isdir(self._cache_file_path):
@@ -235,8 +235,8 @@ class ApolloClient:
return
else:
logger.warning("Sleep...")
except Exception as e:
logger.warning(str(e))
except Exception:
logger.warning("Apollo long polling failed", exc_info=True)
def _get_net_and_set_local(self, namespace: str, n_id: int, call_change: bool = False) -> None:
namespace_data = self.get_json_from_net(namespace)
+2 -2
View File
@@ -686,8 +686,8 @@ class WorkflowAppGenerator(BaseAppGenerator):
try:
with active_workflow_task(application_generate_entity.task_id):
runner.run()
except GenerateTaskStoppedError as e:
logger.warning("Task stopped: %s", str(e))
except GenerateTaskStoppedError:
logger.warning("Task stopped", exc_info=True)
pass
except InvokeAuthorizationError:
queue_manager.publish_error(
@@ -90,8 +90,8 @@ class AnnotationReplyFeature:
)
return annotation
except Exception as e:
logger.warning("Query annotation failed, exception: %s.", str(e))
except Exception:
logger.warning("Query annotation failed.", exc_info=True)
return None
return None
+2 -2
View File
@@ -486,8 +486,8 @@ class ProviderConfiguration(BaseModel):
next_number = max(numbers, default=0) + 1
return f"API KEY {next_number}"
except Exception as e:
logger.warning("Error generating next credential name: %s", str(e))
except Exception:
logger.warning("Error generating next credential name", exc_info=True)
return "API KEY 1"
def _get_provider_names(self):
+2 -2
View File
@@ -923,8 +923,8 @@ class LBModelManager:
provider=self._provider,
credential_type=PluginCredentialType.MODEL,
)
except Exception as e:
logger.warning("Load balancing config %s failed policy compliance check: %s", config.id, str(e))
except Exception:
logger.warning("Load balancing config %s failed policy compliance check", config.id, exc_info=True)
cooldown_load_balancing_configs.append(config)
if len(cooldown_load_balancing_configs) >= len(self._load_balancing_configs):
# all configs are in cooldown or failed policy compliance
+2 -2
View File
@@ -131,8 +131,8 @@ class WordExtractor(BaseExtractor):
continue
try:
response = remote_fetcher.make_request("GET", url)
except Exception as e:
logger.warning("Failed to download image from URL: %s: %s", url, str(e))
except Exception:
logger.warning("Failed to download image from URL: %s", url, exc_info=True)
continue
if response.status_code == 200:
image_ext = mimetypes.guess_extension(response.headers.get("Content-Type", ""))
@@ -468,8 +468,8 @@ class ParagraphIndexProcessor(BaseIndexProcessor):
file, image_detail_config=ImagePromptMessageContent.DETAIL.LOW
)
prompt_message_contents.append(file_content)
except Exception as e:
logger.warning("Failed to convert image file to prompt message content: %s", str(e))
except Exception:
logger.warning("Failed to convert image file to prompt message content", exc_info=True)
continue
# Add text content
@@ -572,8 +572,8 @@ class ParagraphIndexProcessor(BaseIndexProcessor):
access_controller=_file_access_controller,
)
file_objects.append(file_obj)
except Exception as e:
logger.warning("Failed to create File object from UploadFile %s: %s", upload_file.id, str(e))
except Exception:
logger.warning("Failed to create File object from UploadFile %s", upload_file.id, exc_info=True)
continue
return file_objects
@@ -629,8 +629,8 @@ class ParagraphIndexProcessor(BaseIndexProcessor):
storage_key=upload_file.key,
)
file_objects.append(file_obj)
except Exception as e:
logger.warning("Failed to create File object from UploadFile %s: %s", upload_file.id, str(e))
except Exception:
logger.warning("Failed to create File object from UploadFile %s", upload_file.id, exc_info=True)
continue
return file_objects
@@ -86,7 +86,7 @@ class TraceClient:
logger.warning("AliyunTrace API check failed: Unexpected status code: %s", response.status_code)
return False
except httpx.RequestError as e:
logger.warning("AliyunTrace API check failed: %s", str(e))
logger.warning("AliyunTrace API check failed", exc_info=True)
raise ValueError(f"AliyunTrace API check failed: {str(e)}")
def get_project_url(self) -> str:
+4 -4
View File
@@ -243,8 +243,8 @@ class SummaryIndexService:
tokens_list = embedding_model.get_text_embedding_num_tokens([summary_content])
raw_embedding_tokens = tokens_list[0] if tokens_list else 0
embedding_tokens = raw_embedding_tokens if isinstance(raw_embedding_tokens, int) else 0
except Exception as e:
logger.warning("Failed to calculate embedding tokens for summary: %s", str(e))
except Exception:
logger.warning("Failed to calculate embedding tokens for summary", exc_info=True)
# Create document with summary content and metadata
summary_document = Document(
@@ -914,8 +914,8 @@ class SummaryIndexService:
try:
vector = Vector(dataset, session=session)
vector.delete_by_ids(summary_node_ids)
except Exception as e:
logger.warning("Failed to remove summary vectors: %s", str(e))
except Exception:
logger.warning("Failed to remove summary vectors", exc_info=True)
# Disable summary records (don't delete)
now = naive_utc_now()
+2 -2
View File
@@ -128,8 +128,8 @@ def add_document_to_index_task(dataset_document_id: str):
dataset=dataset,
segment_ids=segment_ids_list,
)
except Exception as e:
logger.warning("Failed to enable summaries for document %s: %s", dataset_document.id, str(e))
except Exception:
logger.warning("Failed to enable summaries for document %s", dataset_document.id, exc_info=True)
end_at = time.perf_counter()
logger.info(
+2 -2
View File
@@ -73,8 +73,8 @@ def disable_segment_from_index_task(segment_id: str):
segment_ids=[segment.id],
disabled_by=segment.disabled_by,
)
except Exception as e:
logger.warning("Failed to disable summary for segment %s: %s", segment.id, str(e))
except Exception:
logger.warning("Failed to disable summary for segment %s", segment.id, exc_info=True)
end_at = time.perf_counter()
logger.info(
@@ -81,8 +81,8 @@ def disable_segments_from_index_task(segment_ids: list, dataset_id: str, documen
segment_ids=segment_ids_list,
disabled_by=disabled_by,
)
except Exception as e:
logger.warning("Failed to disable summaries for segments: %s", str(e))
except Exception:
logger.warning("Failed to disable summaries for segments", exc_info=True)
end_at = time.perf_counter()
logger.info(click.style(f"Segments removed from index latency: {end_at - start_at}", fg="green"))
+2 -2
View File
@@ -117,8 +117,8 @@ def enable_segment_to_index_task(segment_id: str):
dataset=dataset,
segment_ids=[segment.id],
)
except Exception as e:
logger.warning("Failed to enable summary for segment %s: %s", segment.id, str(e))
except Exception:
logger.warning("Failed to enable summary for segment %s", segment.id, exc_info=True)
end_at = time.perf_counter()
logger.info(click.style(f"Segment enabled to index: {segment.id} latency: {end_at - start_at}", fg="green"))
+2 -2
View File
@@ -117,8 +117,8 @@ def enable_segments_to_index_task(segment_ids: list, dataset_id: str, document_i
dataset=dataset,
segment_ids=segment_ids_list,
)
except Exception as e:
logger.warning("Failed to enable summaries for segments: %s", str(e))
except Exception:
logger.warning("Failed to enable summaries for segments", exc_info=True)
end_at = time.perf_counter()
logger.info(click.style(f"Segments enabled to index latency: {end_at - start_at}", fg="green"))
+2 -2
View File
@@ -58,8 +58,8 @@ def remove_document_from_index_task(document_id: str):
segment_ids=segment_ids_list,
disabled_by=document.disabled_by,
)
except Exception as e:
logger.warning("Failed to disable summaries for document %s: %s", document.id, str(e))
except Exception:
logger.warning("Failed to disable summaries for document %s", document.id, exc_info=True)
index_node_ids = [segment.index_node_id for segment in segments if segment.index_node_id]
if index_node_ids:
@@ -712,6 +712,32 @@ class TestParagraphIndexProcessor:
assert files == []
assert sum(1 for r in caplog.records if r.levelno == logging.WARNING) == 1
def test_extract_images_from_text_warning_carries_traceback(self, caplog: pytest.LogCaptureFixture) -> None:
"""The build failure is logged at WARNING with the traceback attached, not just str(exception)."""
text = "![img](/files/11111111-1111-1111-1111-111111111111/image-preview)"
session = self.session
session.add(self._upload_file(file_id="11111111-1111-1111-1111-111111111111"))
session.flush()
with (
patch(
"core.rag.index_processor.processor.paragraph_index_processor.build_from_mapping",
side_effect=RuntimeError("build failed"),
),
caplog.at_level(logging.WARNING, logger="core.rag.index_processor.processor.paragraph_index_processor"),
):
ParagraphIndexProcessor._extract_images_from_text("tenant-1", text, session)
record = next(r for r in caplog.records if r.levelno == logging.WARNING)
assert record.exc_info is not None
_, exc_value, exc_traceback = record.exc_info
assert isinstance(exc_value, RuntimeError)
assert exc_traceback is not None
# The formatted output carries the call chain, and the message itself no longer inlines the exception.
assert "Traceback (most recent call last)" in caplog.text
assert "RuntimeError: build failed" in caplog.text
assert "build failed" not in record.getMessage()
def test_extract_images_from_segment_attachments(self, caplog: pytest.LogCaptureFixture) -> None:
session = self.session
uploads = [