refactor: fix decision handling and error message extraction in Notion tools

- Improved decision extraction logic in create, delete, and update Notion page tools to ensure proper handling of approval decisions.
- Added a static method to NotionHistoryConnector for consistent error message extraction from API responses, enhancing readability and maintainability.
This commit is contained in:
DESKTOP-RTLN3BA\$punk 2026-02-16 02:14:26 -08:00
parent 28d93aed2a
commit 9390f195cc
4 changed files with 49 additions and 19 deletions

View file

@ -107,7 +107,9 @@ def create_create_notion_page_tool(
}
)
decisions = approval.get("decisions", [])
decisions_raw = approval.get("decisions", []) if isinstance(approval, dict) else []
decisions = decisions_raw if isinstance(decisions_raw, list) else [decisions_raw]
decisions = [d for d in decisions if isinstance(d, dict)]
if not decisions:
logger.warning("No approval decision received")
return {
@ -126,8 +128,15 @@ def create_create_notion_page_tool(
"message": "User declined. The page was not created. Do not ask again or suggest alternatives.",
}
edited_action = decision.get("edited_action", {})
final_params = edited_action.get("args", {}) if edited_action else {}
edited_action = decision.get("edited_action")
final_params: dict[str, Any] = {}
if isinstance(edited_action, dict):
edited_args = edited_action.get("args")
if isinstance(edited_args, dict):
final_params = edited_args
elif isinstance(decision.get("args"), dict):
# Some interrupt payloads place args directly on the decision.
final_params = decision["args"]
final_title = final_params.get("title", title)
final_content = final_params.get("content", content)

View file

@ -119,7 +119,9 @@ def create_delete_notion_page_tool(
}
)
decisions = approval.get("decisions", [])
decisions_raw = approval.get("decisions", []) if isinstance(approval, dict) else []
decisions = decisions_raw if isinstance(decisions_raw, list) else [decisions_raw]
decisions = [d for d in decisions if isinstance(d, dict)]
if not decisions:
logger.warning("No approval decision received")
return {
@ -139,8 +141,15 @@ def create_delete_notion_page_tool(
}
# Extract edited action arguments (if user modified the checkbox)
edited_action = decision.get("edited_action", {})
final_params = edited_action.get("args", {}) if edited_action else {}
edited_action = decision.get("edited_action")
final_params: dict[str, Any] = {}
if isinstance(edited_action, dict):
edited_args = edited_action.get("args")
if isinstance(edited_args, dict):
final_params = edited_args
elif isinstance(decision.get("args"), dict):
# Some interrupt payloads place args directly on the decision.
final_params = decision["args"]
final_page_id = final_params.get("page_id", page_id)
final_connector_id = final_params.get(

View file

@ -128,7 +128,9 @@ def create_update_notion_page_tool(
}
)
decisions = approval.get("decisions", [])
decisions_raw = approval.get("decisions", []) if isinstance(approval, dict) else []
decisions = decisions_raw if isinstance(decisions_raw, list) else [decisions_raw]
decisions = [d for d in decisions if isinstance(d, dict)]
if not decisions:
logger.warning("No approval decision received")
return {
@ -147,8 +149,15 @@ def create_update_notion_page_tool(
"message": "User declined. The page was not updated. Do not ask again or suggest alternatives.",
}
edited_action = decision.get("edited_action", {})
final_params = edited_action.get("args", {}) if edited_action else {}
edited_action = decision.get("edited_action")
final_params: dict[str, Any] = {}
if isinstance(edited_action, dict):
edited_args = edited_action.get("args")
if isinstance(edited_args, dict):
final_params = edited_args
elif isinstance(decision.get("args"), dict):
# Some interrupt payloads place args directly on the decision.
final_params = decision["args"]
final_page_id = final_params.get("page_id", page_id)
final_content = final_params.get("content", content)

View file

@ -442,6 +442,16 @@ class NotionHistoryConnector:
if page_title not in self._pages_with_skipped_content:
self._pages_with_skipped_content.append(page_title)
@staticmethod
def _api_error_message(error: APIResponseError) -> str:
"""Extract a stable, human-readable message from Notion API errors."""
body = getattr(error, "body", None)
if isinstance(body, dict):
return str(body.get("message", str(error)))
if body:
return str(body)
return str(error)
async def __aenter__(self):
"""Async context manager entry."""
return self
@ -998,7 +1008,7 @@ class NotionHistoryConnector:
except APIResponseError as e:
logger.error(f"Notion API error creating page: {e}")
error_msg = e.body.get("message", str(e)) if hasattr(e, "body") else str(e)
error_msg = self._api_error_message(e)
return {
"status": "error",
"message": f"Failed to create Notion page: {error_msg}",
@ -1087,7 +1097,7 @@ class NotionHistoryConnector:
except APIResponseError as e:
logger.error(f"Notion API error updating page: {e}")
error_msg = e.body.get("message", str(e)) if hasattr(e, "body") else str(e)
error_msg = self._api_error_message(e)
return {
"status": "error",
"message": f"Failed to update Notion page: {error_msg}",
@ -1136,14 +1146,7 @@ class NotionHistoryConnector:
except APIResponseError as e:
logger.error(f"Notion API error deleting page: {e}")
# Handle both dict and string body formats
if hasattr(e, "body"):
if isinstance(e.body, dict):
error_msg = e.body.get("message", str(e))
else:
error_msg = str(e.body) if e.body else str(e)
else:
error_msg = str(e)
error_msg = self._api_error_message(e)
return {
"status": "error",
"message": f"Failed to delete Notion page: {error_msg}",