ref: Propagate traceback in exception logs (#4030)
Propagate traceback in exception logs
This commit is contained in:
parent
79a1257b7d
commit
32b5da8d1f
57 changed files with 202 additions and 217 deletions
|
|
@ -72,8 +72,8 @@ def run_migrations_online() -> None:
|
|||
initialize_settings_service()
|
||||
service_manager.register_factory(DatabaseServiceFactory())
|
||||
connectable = get_db_service().engine
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting database engine: {e}")
|
||||
except Exception:
|
||||
logger.exception("Error getting database engine")
|
||||
url = os.getenv("LANGFLOW_DATABASE_URL")
|
||||
url = url or config.get_main_option("sqlalchemy.url")
|
||||
if url:
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ class AsyncStreamingLLMCallbackHandleSIO(AsyncCallbackHandler):
|
|||
# This is to emulate the stream of tokens
|
||||
for resp in resps:
|
||||
await self.socketio_service.emit_token(to=self.sid, data=resp.model_dump())
|
||||
except Exception as exc:
|
||||
logger.error(f"Error sending response: {exc}")
|
||||
except Exception:
|
||||
logger.exception("Error sending response")
|
||||
|
||||
async def on_tool_error(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ async def try_running_celery_task(vertex, user_id):
|
|||
|
||||
task = build_vertex.delay(vertex)
|
||||
vertex.task_id = task.id
|
||||
except Exception as exc:
|
||||
logger.debug(f"Error running task in celery: {exc}")
|
||||
except Exception:
|
||||
logger.opt(exception=True).debug("Error running task in celery")
|
||||
vertex.task_id = None
|
||||
await vertex.build(user_id=user_id)
|
||||
return vertex
|
||||
|
|
@ -135,8 +135,7 @@ async def retrieve_vertices_order(
|
|||
)
|
||||
if "stream or streaming set to True" in str(exc):
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
logger.error(f"Error checking build status: {exc}")
|
||||
logger.exception(exc)
|
||||
logger.exception("Error checking build status")
|
||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
||||
|
||||
|
|
@ -169,7 +168,7 @@ async def build_flow(
|
|||
try:
|
||||
first_layer = graph.sort_vertices(stop_component_id, start_component_id)
|
||||
except Exception as exc:
|
||||
logger.error(exc)
|
||||
logger.exception(exc)
|
||||
first_layer = graph.sort_vertices()
|
||||
else:
|
||||
first_layer = graph.sort_vertices()
|
||||
|
|
@ -203,8 +202,7 @@ async def build_flow(
|
|||
)
|
||||
if "stream or streaming set to True" in str(exc):
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
logger.error(f"Error checking build status: {exc}")
|
||||
logger.exception(exc)
|
||||
logger.exception("Error checking build status")
|
||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
||||
async def _build_vertex(vertex_id: str, graph: Graph, event_manager: EventManager) -> VertexBuildResponse:
|
||||
|
|
@ -241,7 +239,7 @@ async def build_flow(
|
|||
tb = exc.formatted_traceback
|
||||
else:
|
||||
tb = traceback.format_exc()
|
||||
logger.exception(f"Error building Component: {exc}")
|
||||
logger.exception("Error building Component")
|
||||
params = format_exception_message(exc)
|
||||
message = {"errorMessage": params, "stackTrace": tb}
|
||||
valid = False
|
||||
|
|
@ -315,8 +313,7 @@ async def build_flow(
|
|||
componentErrorMessage=str(exc),
|
||||
),
|
||||
)
|
||||
logger.error(f"Error building Component: \n\n{exc}")
|
||||
logger.exception(exc)
|
||||
logger.exception("Error building Component")
|
||||
message = parse_exception(exc)
|
||||
raise HTTPException(status_code=500, detail=message) from exc
|
||||
|
||||
|
|
@ -524,7 +521,7 @@ async def build_vertex(
|
|||
tb = exc.formatted_traceback
|
||||
else:
|
||||
tb = traceback.format_exc()
|
||||
logger.exception(f"Error building Component: {exc}")
|
||||
logger.exception("Error building Component")
|
||||
params = format_exception_message(exc)
|
||||
message = {"errorMessage": params, "stackTrace": tb}
|
||||
valid = False
|
||||
|
|
@ -602,8 +599,7 @@ async def build_vertex(
|
|||
componentErrorMessage=str(exc),
|
||||
),
|
||||
)
|
||||
logger.error(f"Error building Component: \n\n{exc}")
|
||||
logger.exception(exc)
|
||||
logger.exception("Error building Component")
|
||||
message = parse_exception(exc)
|
||||
raise HTTPException(status_code=500, detail=message) from exc
|
||||
|
||||
|
|
@ -695,7 +691,7 @@ async def build_vertex_stream(
|
|||
raise ValueError(msg)
|
||||
|
||||
except Exception as exc:
|
||||
logger.exception(f"Error building Component: {exc}")
|
||||
logger.exception("Error building Component")
|
||||
exc_message = parse_exception(exc)
|
||||
if exc_message == "The message must be an iterator or an async iterator.":
|
||||
exc_message = "This stream has already been closed."
|
||||
|
|
|
|||
|
|
@ -168,8 +168,8 @@ async def simple_run_flow_task(
|
|||
api_key_user=api_key_user,
|
||||
)
|
||||
|
||||
except Exception as exc:
|
||||
logger.exception(f"Error running flow {flow.id} task: {exc}")
|
||||
except Exception:
|
||||
logger.exception(f"Error running flow {flow.id} task")
|
||||
|
||||
|
||||
@router.post("/run/{flow_id_or_name}", response_model=RunResponse, response_model_exclude_none=True)
|
||||
|
|
@ -280,7 +280,7 @@ async def simplified_run_flow(
|
|||
logger.exception(exc)
|
||||
raise APIException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=exc, flow=flow) from exc
|
||||
except InvalidChatInputException as exc:
|
||||
logger.error(exc)
|
||||
logger.exception(exc)
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
|
||||
except Exception as exc:
|
||||
logger.exception(exc)
|
||||
|
|
@ -293,7 +293,6 @@ async def simplified_run_flow(
|
|||
runErrorMessage=str(exc),
|
||||
),
|
||||
)
|
||||
logger.exception(exc)
|
||||
raise APIException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=exc, flow=flow) from exc
|
||||
|
||||
|
||||
|
|
@ -478,15 +477,15 @@ async def experimental_run_flow(
|
|||
except sa.exc.StatementError as exc:
|
||||
# StatementError('(builtins.ValueError) badly formed hexadecimal UUID string')
|
||||
if "badly formed hexadecimal UUID string" in str(exc):
|
||||
logger.error(f"Flow ID {flow_id_str} is not a valid UUID")
|
||||
logger.exception(f"Flow ID {flow_id_str} is not a valid UUID")
|
||||
# This means the Flow ID is not a valid UUID which means it can't find the flow
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
|
||||
except ValueError as exc:
|
||||
if f"Flow {flow_id_str} not found" in str(exc):
|
||||
logger.error(f"Flow {flow_id_str} not found")
|
||||
logger.exception(f"Flow {flow_id_str} not found")
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
|
||||
if f"Session {session_id} not found" in str(exc):
|
||||
logger.error(f"Session {session_id} not found")
|
||||
logger.exception(f"Session {session_id} not found")
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc
|
||||
logger.exception(exc)
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc)) from exc
|
||||
|
|
@ -573,7 +572,7 @@ async def create_upload_file(
|
|||
file_path=file_path,
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.error(f"Error saving file: {exc}")
|
||||
logger.exception("Error saving file")
|
||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ def read_flows(
|
|||
if example_flow.id not in flow_ids:
|
||||
flows.append(example_flow) # type: ignore
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
logger.exception(e)
|
||||
|
||||
if remove_example_flows:
|
||||
flows = [flow for flow in flows if flow.folder_id != folder.id]
|
||||
|
|
|
|||
|
|
@ -19,5 +19,5 @@ def get_starter_projects(
|
|||
try:
|
||||
return get_starter_projects_dump()
|
||||
except Exception as exc:
|
||||
logger.error(exc)
|
||||
logger.exception(exc)
|
||||
raise HTTPException(status_code=500, detail=str(exc)) from exc
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ def get_optional_user_store_api_key(
|
|||
return None
|
||||
try:
|
||||
return auth_utils.decrypt_api_key(user.store_api_key, settings_service)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to decrypt API key: {e}")
|
||||
except Exception:
|
||||
logger.exception("Failed to decrypt API key")
|
||||
return user.store_api_key
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -133,9 +133,9 @@ def validate_prompt(prompt_template: str, silent_errors: bool = False) -> list[s
|
|||
try:
|
||||
PromptTemplate(template=prompt_template, input_variables=input_variables)
|
||||
except Exception as exc:
|
||||
logger.error(f"Invalid prompt: {exc}")
|
||||
msg = f"Invalid prompt: {exc}"
|
||||
logger.exception(msg)
|
||||
if not silent_errors:
|
||||
msg = f"Invalid prompt: {exc}"
|
||||
raise ValueError(msg) from exc
|
||||
|
||||
return input_variables
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ class FlowTool(BaseTool):
|
|||
tweaks = self.build_tweaks_dict(args, kwargs)
|
||||
try:
|
||||
run_id = self.graph.run_id if self.graph else None
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to set run_id: {e}")
|
||||
except Exception:
|
||||
logger.opt(exception=True).warning("Failed to set run_id")
|
||||
run_id = None
|
||||
run_outputs = await run_flow(
|
||||
tweaks={key: {"input_value": value} for key, value in tweaks.items()},
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ class NotionPageUpdate(LCToolComponent):
|
|||
parsed_properties = json.loads(properties)
|
||||
except json.JSONDecodeError as e:
|
||||
error_message = f"Invalid JSON format for properties: {e}"
|
||||
logger.error(error_message)
|
||||
logger.exception(error_message)
|
||||
return error_message
|
||||
|
||||
else:
|
||||
|
|
@ -98,15 +98,15 @@ class NotionPageUpdate(LCToolComponent):
|
|||
if e.response is not None:
|
||||
error_message += f"\nStatus code: {e.response.status_code}"
|
||||
error_message += f"\nResponse body: {e.response.text}"
|
||||
logger.error(error_message)
|
||||
logger.exception(error_message)
|
||||
return error_message
|
||||
except requests.exceptions.RequestException as e:
|
||||
error_message = f"An error occurred while making the request: {e}"
|
||||
logger.error(error_message)
|
||||
logger.exception(error_message)
|
||||
return error_message
|
||||
except Exception as e:
|
||||
error_message = f"An unexpected error occurred: {e}"
|
||||
logger.error(error_message)
|
||||
logger.exception(error_message)
|
||||
return error_message
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
|
|
|
|||
|
|
@ -87,13 +87,13 @@ class APIRequestComponent(Component):
|
|||
try:
|
||||
json_data = json.loads(parsed.data)
|
||||
build_config["body"]["value"] = json_data
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(f"Error decoding JSON data: {e}")
|
||||
except json.JSONDecodeError:
|
||||
logger.exception("Error decoding JSON data")
|
||||
else:
|
||||
build_config["body"]["value"] = {}
|
||||
except Exception as exc:
|
||||
logger.error(f"Error parsing curl: {exc}")
|
||||
msg = f"Error parsing curl: {exc}"
|
||||
logger.exception(msg)
|
||||
raise ValueError(msg) from exc
|
||||
return build_config
|
||||
|
||||
|
|
@ -120,9 +120,9 @@ class APIRequestComponent(Component):
|
|||
try:
|
||||
body = json.loads(body)
|
||||
except Exception as e:
|
||||
logger.error(f"Error decoding JSON data: {e}")
|
||||
body = None
|
||||
msg = f"Error decoding JSON data: {e}"
|
||||
logger.exception(msg)
|
||||
body = None
|
||||
raise ValueError(msg) from e
|
||||
|
||||
data = body if body else None
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ class SubFlowComponent(CustomComponent):
|
|||
inputs = get_flow_inputs(graph)
|
||||
# Add inputs to the build config
|
||||
build_config = self.add_inputs_to_build_config(inputs, build_config)
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting flow {field_value}: {e}")
|
||||
except Exception:
|
||||
logger.exception(f"Error getting flow {field_value}")
|
||||
|
||||
return build_config
|
||||
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ class AIMLEmbeddingsImpl(BaseModel, Embeddings):
|
|||
httpx.RequestError,
|
||||
json.JSONDecodeError,
|
||||
KeyError,
|
||||
) as e:
|
||||
logger.error(f"Error occurred: {e}")
|
||||
):
|
||||
logger.exception("Error occurred")
|
||||
raise
|
||||
|
||||
return embeddings # type: ignore
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@ class FlowToolComponent(LCToolComponent):
|
|||
graph = Graph.from_payload(flow_data.data["data"])
|
||||
try:
|
||||
graph.set_run_id(self.graph.run_id)
|
||||
except Exception as e:
|
||||
logger.warning(f"Failed to set run_id: {e}")
|
||||
except Exception:
|
||||
logger.opt(exception=True).warning("Failed to set run_id")
|
||||
inputs = get_flow_inputs(graph)
|
||||
tool = FlowTool(
|
||||
name=self.name,
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ class SubFlowComponent(Component):
|
|||
inputs = get_flow_inputs(graph)
|
||||
# Add inputs to the build config
|
||||
build_config = self.add_inputs_to_build_config(inputs, build_config)
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting flow {field_value}: {e}")
|
||||
except Exception:
|
||||
logger.exception(f"Error getting flow {field_value}")
|
||||
|
||||
return build_config
|
||||
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@ class ComposioAPIComponent(LCToolComponent):
|
|||
if auth_schemes[0].auth_mode == "API_KEY":
|
||||
return self._process_api_key_auth(entity, app)
|
||||
return self._initiate_default_connection(entity, app)
|
||||
except Exception as exc:
|
||||
logger.error(f"Authorization error: {exc}")
|
||||
except Exception:
|
||||
logger.exception("Authorization error")
|
||||
return "Error"
|
||||
|
||||
def _process_api_key_auth(self, entity: Any, app: str) -> str:
|
||||
|
|
|
|||
|
|
@ -198,11 +198,11 @@ class ElasticsearchVectorStoreComponent(LCVectorStoreComponent):
|
|||
msg = f"Invalid search type: {self.search_type}"
|
||||
raise ValueError(msg)
|
||||
except Exception as e:
|
||||
logger.error(f"Search query failed: {e}")
|
||||
msg = (
|
||||
"Error occurred while querying the Elasticsearch VectorStore,"
|
||||
" there is no Data into the VectorStore."
|
||||
)
|
||||
logger.exception(msg)
|
||||
raise ValueError(msg) from e
|
||||
return [
|
||||
{"page_content": doc.page_content, "metadata": doc.metadata, "score": score} for doc, score in results
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import json
|
||||
import traceback
|
||||
from typing import Any
|
||||
|
||||
from langchain_community.vectorstores import OpenSearchVectorSearch
|
||||
|
|
@ -125,7 +124,7 @@ class OpenSearchVectorStoreComponent(LCVectorStoreComponent):
|
|||
from langchain_community.vectorstores import OpenSearchVectorSearch
|
||||
except ImportError as e:
|
||||
error_message = f"Failed to import required modules: {e}"
|
||||
logger.error(error_message)
|
||||
logger.exception(error_message)
|
||||
raise ImportError(error_message) from e
|
||||
|
||||
try:
|
||||
|
|
@ -141,7 +140,7 @@ class OpenSearchVectorStoreComponent(LCVectorStoreComponent):
|
|||
)
|
||||
except Exception as e:
|
||||
error_message = f"Failed to create OpenSearchVectorSearch instance: {e}"
|
||||
logger.error(error_message)
|
||||
logger.exception(error_message)
|
||||
raise RuntimeError(error_message) from e
|
||||
|
||||
if self.ingest_data:
|
||||
|
|
@ -168,8 +167,7 @@ class OpenSearchVectorStoreComponent(LCVectorStoreComponent):
|
|||
vector_store.add_documents(documents)
|
||||
except Exception as e:
|
||||
error_message = f"Error adding documents to Vector Store: {e}"
|
||||
logger.error(error_message)
|
||||
logger.error(f"Traceback: {traceback.format_exc()}")
|
||||
logger.exception(error_message)
|
||||
raise RuntimeError(error_message) from e
|
||||
else:
|
||||
logger.debug("No documents to add to the Vector Store.")
|
||||
|
|
@ -188,7 +186,7 @@ class OpenSearchVectorStoreComponent(LCVectorStoreComponent):
|
|||
hybrid_query = json.loads(self.hybrid_search_query)
|
||||
except json.JSONDecodeError as e:
|
||||
error_message = f"Invalid hybrid search query JSON: {e}"
|
||||
logger.error(error_message)
|
||||
logger.exception(error_message)
|
||||
raise ValueError(error_message) from e
|
||||
|
||||
results = vector_store.client.search(index=self.index_name, body=hybrid_query)
|
||||
|
|
@ -232,13 +230,12 @@ class OpenSearchVectorStoreComponent(LCVectorStoreComponent):
|
|||
return [{"page_content": doc.page_content, "metadata": doc.metadata} for doc in results]
|
||||
|
||||
error_message = f"Invalid search type:: {self.search_type}"
|
||||
logger.error(error_message)
|
||||
logger.exception(error_message)
|
||||
raise ValueError(error_message)
|
||||
|
||||
except Exception as e:
|
||||
error_message = f"Error during search: {e}"
|
||||
logger.error(error_message)
|
||||
logger.error(f"Traceback: {traceback.format_exc()}")
|
||||
logger.exception(error_message)
|
||||
raise RuntimeError(error_message) from e
|
||||
|
||||
def search_documents(self) -> list[Data]:
|
||||
|
|
@ -260,6 +257,5 @@ class OpenSearchVectorStoreComponent(LCVectorStoreComponent):
|
|||
return retrieved_data
|
||||
except Exception as e:
|
||||
error_message = f"Error during document search: {e}"
|
||||
logger.error(error_message)
|
||||
logger.error(f"Traceback: {traceback.format_exc()}")
|
||||
logger.exception(error_message)
|
||||
raise RuntimeError(error_message) from e
|
||||
|
|
|
|||
|
|
@ -340,8 +340,8 @@ class CodeParser:
|
|||
for import_node in import_nodes:
|
||||
self.parse_imports(import_node)
|
||||
nodes.append(class_node)
|
||||
except Exception as exc:
|
||||
logger.error(f"Error finding base class node: {exc}")
|
||||
except Exception:
|
||||
logger.exception("Error finding base class node")
|
||||
nodes.insert(0, node)
|
||||
class_details = ClassCodeDetails(
|
||||
name=node.name,
|
||||
|
|
|
|||
|
|
@ -215,9 +215,8 @@ class DirectoryReader:
|
|||
"""
|
||||
try:
|
||||
file_content = self.read_file_content(file_path)
|
||||
except Exception as exc:
|
||||
logger.exception(exc)
|
||||
logger.error(f"Error while reading file {file_path}: {exc}")
|
||||
except Exception:
|
||||
logger.exception(f"Error while reading file {file_path}")
|
||||
return False, f"Could not read {file_path}"
|
||||
|
||||
if file_content is None:
|
||||
|
|
@ -292,9 +291,8 @@ class DirectoryReader:
|
|||
async def process_file_async(self, file_path):
|
||||
try:
|
||||
file_content = self.read_file_content(file_path)
|
||||
except Exception as exc:
|
||||
logger.exception(exc)
|
||||
logger.error(f"Error while reading file {file_path}: {exc}")
|
||||
except Exception:
|
||||
logger.exception(f"Error while reading file {file_path}")
|
||||
return False, f"Could not read {file_path}"
|
||||
|
||||
if file_content is None:
|
||||
|
|
@ -346,8 +344,8 @@ class DirectoryReader:
|
|||
if validation_result:
|
||||
try:
|
||||
output_types = await self.get_output_types_from_code_async(result_content)
|
||||
except Exception as exc:
|
||||
logger.error(f"Error while getting output types from code: {exc}")
|
||||
except Exception:
|
||||
logger.exception("Error while getting output types from code")
|
||||
output_types = [component_name_camelcase]
|
||||
else:
|
||||
output_types = [component_name_camelcase]
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue