Commit fab2736
authored
* fix: standardize error handling across all tool modules (#521)
Replace all ad-hoc {"success": False, "error": "string"} return dicts
with structured helpers from errors.py and helpers.py. All tool-level
failures now raise ToolError (sets isError=true per MCP spec). Batch
item failures within result arrays remain as returned structured dicts.
Patterns applied across 30 tool files (~286 occurrences):
- Pattern A: except blocks → exception_to_structured_error()
- Pattern B: input validation → raise_tool_error(create_error_response())
- Pattern C: WS failures → raise_tool_error(create_error_response())
- Pattern D: batch item failures → create_error_response() (no raise)
Also removes redundant 404 string-check in ha_get_state (already
handled by exception_to_structured_error for HomeAssistantAPIError).
Adds except ToolError: raise guard in all functions where raise_tool_error()
is called inside a try block with a broad except Exception handler, to
prevent ToolError being swallowed and re-mapped to INTERNAL_ERROR.
Updates unit tests and e2e tests that previously asserted on returned
error dicts to use pytest.raises(ToolError) or safe_call_tool().
* fix(tests): update e2e tests for structured error shape
- suggestions now live at result["error"]["suggestions"] not top-level
- use safe_call_tool() for calls expected to raise ToolError
- fix test_label_full_lifecycle, test_get_nonexistent_label,
test_delete_nonexistent_label, test_delete_calendar_event,
test_get_blueprint_not_found, test_import_blueprint_nonexistent_url
* fix(tests): use safe_call_tool for all error-path e2e calls
* test: guard e2e tests against accidental real-HA usage
- AGENTS.md: document that full suite must be run from tests/ dir;
running individual files misses failures CI catches
- conftest.py: fail fast if Docker is unavailable (clear error instead
of cryptic Docker exception)
- conftest.py: abort if HOMEASSISTANT_URL is pre-set in the environment
to prevent accidentally targeting a real HA instance
- conftest.py: fail hard if HA API is not ready after 60s instead of
silently continuing with a broken container
* fix(test): remove pre-set URL guard that fires on dotenv load
config.py calls load_dotenv(tests/.env.test) at import time, which sets
HOMEASSISTANT_URL=http://localhost:8123 into os.environ before the
ha_container_with_fresh_config fixture runs. The guard was tripping on
its own placeholder URL in CI.
Real-HA protection is now: Docker availability check (guard 1),
fail-fast if HA API not ready (guard 3), and AGENTS.md documentation.
* docs: trim AGENTS.md testing note
* fix(tests): fix remaining e2e error-shape mismatches
- test_python_transform: result["error"].lower() → extract message from error dict
- test_lifecycle (jq): call_tool+parse_mcp_result → safe_call_tool + error.message
- test_bulk: safe_call_tool for empty operations test
- test_entity_management: suggestions nested under error, not top-level
- test_backup: available_backups no longer top-level, accept suggestion instead
* fix(tests): fix final batch of e2e error-shape mismatches
- test_resources.py: use safe_call_tool + dict error extraction for
test_inline_empty_content_error
- test_integration_management.py: replace call_tool+assert_mcp_failure
with safe_call_tool + dict error extraction for both delete_config_entry
tests; remove unused assert_mcp_failure import
- labels/test_lifecycle.py: use safe_call_tool for update/delete
nonexistent label and assign to nonexistent entity tests
* fix(tests): fix remaining e2e error-shape mismatches (batch 3)
- test_device_registry.py: extract error message from dict for
nonexistent device get/update/remove assertions
- test_system_tools.py: use safe_call_tool + dict error extraction for
restart/reload error-path tests; fix suggestions lookup under error dict
- test_lifecycle.py (scripts): use safe_call_tool for blueprint script
tests instead of call_tool + enhanced_parse_mcp_result
* fix: address code review feedback on error handling standardization
- smart_search.py: replace return create_error_response() with
exception_to_structured_error() so all 4 tool methods raise ToolError
instead of returning error dicts (contradicted PR contract)
- tools_entities.py: replace hardcoded "SERVICE_CALL_FAILED" and
"ENTITY_NOT_FOUND" strings with ErrorCode enum values
- tools_areas/addons/labels/groups.py: restore logger.error() calls
before exception_to_structured_error() for consistent server-side
logging (was removed inconsistently in original PR)
- tools_services.py: change VALIDATION_INVALID_PARAMETER to
INTERNAL_UNEXPECTED for unexpected HA API response format in
_process_services (not a user input error)
* fix: restore exception_to_structured_error(raise_error=False) in delete handlers
During rebase conflict resolution the old idempotent "not found = success"
pattern was reintroduced in the exception blocks of ha_config_delete_dashboard
and ha_config_delete_dashboard_resource. PR #680 had explicitly removed those
paths in favour of exception_to_structured_error(raise_error=False), which
this commit restores.
1 parent 9e6988a commit fab2736
57 files changed
Lines changed: 2320 additions & 2100 deletions
File tree
- src/ha_mcp/tools
- tests/src
- e2e
- tools
- workflows
- blueprints
- calendar
- config
- convenience
- core
- dashboards
- entities
- integrations
- labels
- registry
- scripts
- system
- unit
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
431 | 431 | | |
432 | 432 | | |
433 | 433 | | |
434 | | - | |
| 434 | + | |
| 435 | + | |
435 | 436 | | |
436 | 437 | | |
437 | | - | |
438 | | - | |
| 438 | + | |
| 439 | + | |
439 | 440 | | |
440 | | - | |
441 | | - | |
| 441 | + | |
| 442 | + | |
442 | 443 | | |
443 | 444 | | |
444 | 445 | | |
445 | 446 | | |
446 | 447 | | |
447 | 448 | | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
448 | 455 | | |
449 | 456 | | |
450 | 457 | | |
| |||
535 | 542 | | |
536 | 543 | | |
537 | 544 | | |
538 | | - | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
539 | 548 | | |
540 | | - | |
| 549 | + | |
| 550 | + | |
541 | 551 | | |
542 | | - | |
543 | | - | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
544 | 563 | | |
545 | | - | |
546 | | - | |
| 564 | + | |
547 | 565 | | |
548 | | - | |
549 | | - | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
550 | 577 | | |
551 | 578 | | |
552 | | - | |
553 | | - | |
554 | | - | |
| 579 | + | |
555 | 580 | | |
556 | | - | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
557 | 588 | | |
558 | | - | |
559 | | - | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
560 | 596 | | |
561 | 597 | | |
562 | | - | |
| 598 | + | |
563 | 599 | | |
564 | | - | |
565 | | - | |
566 | | - | |
567 | 600 | | |
568 | | - | |
569 | | - | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
570 | 606 | | |
571 | 607 | | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
572 | 612 | | |
573 | 613 | | |
574 | 614 | | |
575 | 615 | | |
576 | | - | |
| 616 | + | |
| 617 | + | |
577 | 618 | | |
578 | 619 | | |
579 | 620 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
16 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
17 | 24 | | |
18 | 25 | | |
19 | 26 | | |
| |||
94 | 101 | | |
95 | 102 | | |
96 | 103 | | |
97 | | - | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
98 | 108 | | |
99 | 109 | | |
100 | 110 | | |
101 | 111 | | |
102 | | - | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
103 | 116 | | |
104 | 117 | | |
105 | 118 | | |
| |||
120 | 133 | | |
121 | 134 | | |
122 | 135 | | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
128 | 140 | | |
129 | 141 | | |
130 | 142 | | |
| |||
185 | 197 | | |
186 | 198 | | |
187 | 199 | | |
188 | | - | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
194 | 205 | | |
195 | 206 | | |
196 | 207 | | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
205 | 217 | | |
206 | 218 | | |
207 | | - | |
208 | | - | |
209 | | - | |
210 | | - | |
211 | | - | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
212 | 224 | | |
213 | 225 | | |
214 | 226 | | |
| |||
240 | 252 | | |
241 | 253 | | |
242 | 254 | | |
243 | | - | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
244 | 259 | | |
245 | 260 | | |
246 | 261 | | |
247 | 262 | | |
248 | | - | |
249 | | - | |
250 | | - | |
251 | | - | |
252 | | - | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
253 | 267 | | |
254 | 268 | | |
255 | 269 | | |
256 | 270 | | |
257 | 271 | | |
258 | | - | |
259 | | - | |
260 | | - | |
261 | | - | |
262 | | - | |
263 | | - | |
264 | | - | |
265 | | - | |
266 | | - | |
267 | | - | |
268 | | - | |
269 | | - | |
270 | | - | |
271 | | - | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
272 | 277 | | |
273 | 278 | | |
274 | 279 | | |
| |||
293 | 298 | | |
294 | 299 | | |
295 | 300 | | |
296 | | - | |
297 | | - | |
298 | | - | |
299 | | - | |
300 | | - | |
301 | | - | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
302 | 306 | | |
303 | 307 | | |
304 | 308 | | |
| |||
326 | 330 | | |
327 | 331 | | |
328 | 332 | | |
329 | | - | |
330 | | - | |
331 | | - | |
332 | | - | |
333 | | - | |
334 | | - | |
335 | | - | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
336 | 341 | | |
337 | 342 | | |
338 | | - | |
339 | | - | |
340 | | - | |
341 | | - | |
342 | | - | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
343 | 348 | | |
344 | 349 | | |
345 | 350 | | |
| |||
0 commit comments