Skip to content

Fix/449 dead code exception handlers#450

Open
parthdagia05 wants to merge 1 commit intoEAPD-DRB:mainfrom
parthdagia05:fix/449-dead-code-exception-handlers
Open

Fix/449 dead code exception handlers#450
parthdagia05 wants to merge 1 commit intoEAPD-DRB:mainfrom
parthdagia05:fix/449-dead-code-exception-handlers

Conversation

@parthdagia05
Copy link
Copy Markdown

Linked issue

Existing related work reviewed

  • Issues/PRs reviewed:
    • #89 - Original stack-trace leak report (closed)
    • #90 - Added except OSError JSON handlers that are now unreachable (merged)
    • Commits d38c2dd and b541ecb - "preserve existing IOError behavior" (root cause of the dead code)

Overlap assessment

Why this PR should proceed

  • PR fix: replace bare raise OSError with structured JSON 500 responses #90 intended to return structured JSON 500 responses for filesystem errors, but the except(IOError): raise IOError pattern left above the new handlers makes them unreachable. Clients currently receive raw HTML 500 stack traces, leaking internal details. This is a minimal 6-line deletion that fixes the bug without changing any other behavior.

Summary

  • What changed: Removed except(IOError): raise IOError blocks from 3 route endpoints:
    • API/Routes/Case/CaseRoute.py - /copyCase (lines 106–107)
    • API/Routes/Upload/UploadRoute.py - uploadCaseUnchunked_old (lines 402–403)
    • API/Routes/Upload/UploadRoute.py - uploadXls (lines 652–653)
  • Why: In Python 3.3+, IOError is an alias for OSError. The pattern except(IOError): raise IOError catches any filesystem error (since IOError == OSError), then re-raises it. A raised exception inside an except clause propagates out - it does not fall through to the next except. This made the except OSError: return jsonify(...) handlers added by PR fix: replace bare raise OSError with structured JSON 500 responses #90 completely unreachable.

Validation

  • Tests added/updated (or not applicable) - No new tests needed; this is a 6-line deletion removing dead code. Existing behavior is unchanged except filesystem errors now return JSON instead of stack traces.
  • Validation steps documented
    • Static check: grep -n "except(IOError):" API/Routes/Case/CaseRoute.py API/Routes/Upload/UploadRoute.py - confirms no raise IOError patterns remain
    • Runtime check: Make the data storage directory read-only, then POST /copyCase with a valid session → should return {"message": "A filesystem error occurred.", "status_code": "error"} with HTTP 500 instead of a raw stack trace
  • Evidence attached (logs/screenshots/output as relevant)

Documentation

  • Docs updated in this PR (or not applicable) - No documentation changes needed; this is a bug fix removing dead code.
  • Any setup/workflow changes reflected in repo docs - N/A

Scope check

  • No unrelated refactors
  • Implemented from a feature branch (fix/449-dead-code-exception-handlers)
  • Change is deliverable without upstream OSeMOSYS/MUIO dependency
  • Base repo/branch is EAPD-DRB/MUIOGO:main (not upstream)

Exception rationale

…RB#449)

Remove 'except(IOError): raise IOError' blocks from three route endpoints.
Since IOError is an alias for OSError in Python 3.3+, the raise inside
the first except propagated out and made the subsequent 'except OSError'
JSON error handlers unreachable dead code. Clients received raw 500
stack traces instead of structured JSON error responses.

Affected endpoints:
- /copyCase (CaseRoute.py)
- uploadCaseUnchunked_old (UploadRoute.py)
- uploadXls (UploadRoute.py)

Closes EAPD-DRB#449
@parthdagia05 parthdagia05 force-pushed the fix/449-dead-code-exception-handlers branch from 3213a1e to 8fd48eb Compare April 18, 2026 05:42
@Cypher-CP0
Copy link
Copy Markdown

Hey, good find on the dead code!
Quick question on the approach, instead of removing the except(IOError): raise IOError blocks entirely, was there any consideration to replacing them with explicit except OSError handlers directly? Since IOError == OSError in Python 3.3+, would making that explicit improve readability for future contributors who might not be aware of the alias?
Just curious on the thought process, the deletion approach makes sense too since the handler below already covers it.

@parthdagia05
Copy link
Copy Markdown
Author

@Cypher-CP0
I removed the except(IOError): raise IOError blocks because they were redundant and breaking control flow. Raising inside that block exits the try-except early, making the downstream except OSError handler unreachable.

Replacing it with except OSError would still risk duplicating or shadowing the existing handler, so removal was the cleanest minimal fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Dead-code exception handlers in 3 route endpoints JSON 500 responses from PR #90 never execute

2 participants