feat: enhance error handling and configuration validation
Some checks failed
CI / lint-and-test (push) Failing after 27s
Some checks failed
CI / lint-and-test (push) Failing after 27s
- Added a global exception handler to log unhandled exceptions and return a generic 500 JSON response without exposing details to the client. - Updated the configuration to validate the `DATABASE_URL` format, ensuring it starts with `sqlite://` or `postgresql://`, and log warnings for invalid formats. - Introduced safe parsing for numeric environment variables (`HTTP_PORT`, `INIT_DATA_MAX_AGE_SECONDS`) with defaults on invalid values, including logging warnings for out-of-range values. - Enhanced the duty schedule parser to enforce limits on the number of schedule rows and the length of full names and duty strings, raising appropriate errors when exceeded. - Updated internationalization messages to include generic error responses for import failures and parsing issues, improving user experience. - Added unit tests to verify the new error handling and configuration validation behaviors.
This commit is contained in:
@@ -278,8 +278,8 @@ async def test_handle_duty_schedule_document_non_json_replies_need_json():
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_duty_schedule_document_parse_error_replies_and_clears_user_data():
|
||||
"""handle_duty_schedule_document: parse_duty_schedule raises DutyScheduleParseError -> reply, clear user_data."""
|
||||
async def test_handle_duty_schedule_document_parse_error_replies_generic_and_clears_user_data():
|
||||
"""handle_duty_schedule_document: DutyScheduleParseError -> reply generic message (no str(e)), clear user_data."""
|
||||
message = MagicMock()
|
||||
message.document = _make_document()
|
||||
message.reply_text = AsyncMock()
|
||||
@@ -299,17 +299,17 @@ async def test_handle_duty_schedule_document_parse_error_replies_and_clears_user
|
||||
with patch.object(mod, "parse_duty_schedule") as mock_parse:
|
||||
mock_parse.side_effect = DutyScheduleParseError("Bad JSON")
|
||||
with patch.object(mod, "t") as mock_t:
|
||||
mock_t.return_value = "Parse error: Bad JSON"
|
||||
mock_t.return_value = "The file could not be parsed."
|
||||
await mod.handle_duty_schedule_document(update, context)
|
||||
message.reply_text.assert_called_once_with("Parse error: Bad JSON")
|
||||
mock_t.assert_called_with("en", "import.parse_error", error="Bad JSON")
|
||||
message.reply_text.assert_called_once_with("The file could not be parsed.")
|
||||
mock_t.assert_called_with("en", "import.parse_error_generic")
|
||||
assert "awaiting_duty_schedule_file" not in context.user_data
|
||||
assert "handover_utc_time" not in context.user_data
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_duty_schedule_document_import_error_replies_and_clears_user_data():
|
||||
"""handle_duty_schedule_document: run_import in executor raises -> reply import_error, clear user_data."""
|
||||
async def test_handle_duty_schedule_document_import_error_replies_generic_and_clears_user_data():
|
||||
"""handle_duty_schedule_document: run_import raises -> reply generic message (no str(e)), clear user_data."""
|
||||
message = MagicMock()
|
||||
message.document = _make_document()
|
||||
message.reply_text = AsyncMock()
|
||||
@@ -340,10 +340,10 @@ async def test_handle_duty_schedule_document_import_error_replies_and_clears_use
|
||||
with patch.object(mod, "run_import") as mock_run:
|
||||
mock_run.side_effect = ValueError("DB error")
|
||||
with patch.object(mod, "t") as mock_t:
|
||||
mock_t.return_value = "Import error: DB error"
|
||||
mock_t.return_value = "Import failed. Please try again."
|
||||
await mod.handle_duty_schedule_document(update, context)
|
||||
message.reply_text.assert_called_once_with("Import error: DB error")
|
||||
mock_t.assert_called_with("en", "import.import_error", error="DB error")
|
||||
message.reply_text.assert_called_once_with("Import failed. Please try again.")
|
||||
mock_t.assert_called_with("en", "import.import_error_generic")
|
||||
assert "awaiting_duty_schedule_file" not in context.user_data
|
||||
assert "handover_utc_time" not in context.user_data
|
||||
|
||||
|
||||
Reference in New Issue
Block a user