Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
INHERIT: docs/mkdocs-base.yml

site_name: pycharting
site_description: Add your description here.
site_description: High-performance financial charting library for OHLC data visualization with technical indicators
site_url: https://alihaskar.github.io/pycharting/
repo_url: https://github.com/alihaskar/pycharting
repo_name: alihaskar/pycharting
Expand Down
17 changes: 16 additions & 1 deletion src/pycharting/api/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

from pycharting.api.routes import _data_managers
from pycharting.core.lifecycle import ChartServer
from pycharting.data.ingestion import DataManager, SubplotSpec
from pycharting.data.ingestion import DataManager, DataValidationError, SubplotSpec

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -259,12 +259,27 @@ def plot(
_notify("\n⚠️ Interrupted - stopping server...")
_active_server.stop_server()

except DataValidationError as e:
# Input data failed validation — the user can fix this by correcting
# their arrays before calling plot() again.
logger.error(f"Invalid input data: {e}", exc_info=True)
_notify(f"\n✗ Invalid input data: {e}\n")

return {
"status": "error",
"stage": "validation",
"error": str(e),
"session_id": session_id,
}
except Exception as e:
# Server startup, browser launch, or other runtime failure — not
# something the caller's data can fix.
logger.error(f"Error creating chart: {e}", exc_info=True)
_notify(f"\n✗ Error creating chart: {e}\n")

return {
"status": "error",
"stage": "server",
"error": str(e),
"session_id": session_id,
}
Expand Down
18 changes: 18 additions & 0 deletions tests/pycharting/api/test_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,24 @@ def test_plot_with_invalid_data():

assert result["status"] == "error"
assert "error" in result
# A validation failure must be reported as such, distinct from server/runtime errors.
assert result["stage"] == "validation"


def test_plot_server_startup_failure_reported_as_server_stage():
"""A non-validation failure (e.g. server startup) is reported with stage='server'."""
n = 20
data = np.random.randn(n) + 100
index = np.arange(n)

# Valid data passes validation, so the error must come from a later stage.
with patch("pycharting.api.interface.ChartServer") as mock_server:
mock_server.side_effect = RuntimeError("boom: could not start server")
result = plot(index, close=data, open_browser=False, block=False)

assert result["status"] == "error"
assert result["stage"] == "server"
assert "boom" in result["error"]


@patch("webbrowser.open")
Expand Down