Repository: ploomber/jupysql
Pull request #832 (2023-08-25 04:56:27)

show warning if default connection fails to initialize
## Describe your changes

## Issue number

Closes https://github.com/ploomber/jupysql/issues/828

## Checklist before requesting a review

- [ ] Performed a self-review of my code
- [ ] Formatted my code with [`pkgmt format`](https://ploomber-contributing.readthedocs.io/en/latest/contributing/pr.html#linting-formatting)
- [ ] Added [tests](https://ploomber-contributing.readthedocs.io/en/latest/contributing/pr.html#testing) (when necessary).
- [ ] Added [docstring](https://ploomber-contributing.readthedocs.io/en/latest/contributing/pr.html#documenting-changes-and-new-features) documentation and update the [changelog](https://ploomber-contributing.readthedocs.io/en/latest/contributing/pr.html#changelog) (when needed)



<!-- readthedocs-preview jupysql start -->
----
:books: Documentation preview :books:: https://jupysql--832.org.readthedocs.build/en/832/

<!-- readthedocs-preview jupysql end -->


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e925cfb..8bdd033 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
 
 * [Feature] Automatically connect if the `dsn_filename` (defaults to `~/.jupysql/connections.ini`) contains a `default` section
 * [Feature] Add `%sqlcmd connect` to see existing connections and create new ones (#632)
+* [Fix] Display a warning (instead of raising an error) if the `default` connection in the `.ini` file cannot start
 
 ## 0.10.0 (2023-08-19)
 
diff --git a/src/sql/connection/connection.py b/src/sql/connection/connection.py
index dd03cc7..e0831af 100644
--- a/src/sql/connection/connection.py
+++ b/src/sql/connection/connection.py
@@ -411,12 +411,21 @@ class ConnectionManager:
         default_url = connections_file.get_default_connection_url()
 
         if default_url is not None:
-            cls.set(
-                default_url,
-                displaycon=False,
-                alias="default",
-                config=config,
-            )
+            try:
+                cls.set(
+                    default_url,
+                    displaycon=False,
+                    alias="default",
+                    config=config,
+                )
+            except Exception as e:
+                # this is executed during the magic initialization, we don't want
+                # to raise an exception here because it would prevent the magic
+                # from being used
+                display.message_warning(
+                    "WARNING: Cannot start default connection from .ini file:"
+                    f"\n\n{str(e)}"
+                )
 
 
 class AbstractConnection(abc.ABC):
diff --git a/src/sql/display.py b/src/sql/display.py
index e7cfdb0..ae0df3d 100644
--- a/src/sql/display.py
+++ b/src/sql/display.py
@@ -72,7 +72,8 @@ class Message:
 
     def __init__(self, message, style=None) -> None:
         self._message = message
-        self._message_html = html.escape(message)
+        # escape html and replace newlines with <br> tags so newlines are displayed
+        self._message_html = html.escape(message).replace("\n\n", "<br>")
         self._style = "" or style
 
     def _repr_html_(self):


Test patch:
diff --git a/src/tests/test_config.py b/src/tests/test_config.py
index 75906d1..4591f1e 100644
--- a/src/tests/test_config.py
+++ b/src/tests/test_config.py
@@ -109,6 +109,24 @@ drivername = duckdb
     assert ConnectionManager.current.dialect == "duckdb"
 
 
+def test_magic_initialization_when_default_connection_fails(
+    tmp_empty, ip_no_magics, capsys
+):
+    ip_no_magics.run_cell("%config SqlMagic.dsn_filename = 'connections.ini'")
+
+    Path("connections.ini").write_text(
+        """
+[default]
+drivername = someunknowndriver
+"""
+    )
+
+    load_ipython_extension(ip_no_magics)
+
+    captured = capsys.readouterr()
+    assert "Cannot start default connection" in captured.out
+
+
 def test_magic_initialization_with_no_pyproject(tmp_empty, ip_no_magics):
     load_ipython_extension(ip_no_magics)