Skip to content

Commit 70fb67f

Browse files
committed
fix: handle connection failures (#110)
1 parent 0dc1982 commit 70fb67f

4 files changed

Lines changed: 63 additions & 2 deletions

File tree

‎databusclient/api/download.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,21 @@ class DownloadAuthError(Exception):
344344
"""Raised when an authorization problem occurs during download."""
345345

346346

347+
def format_download_connection_error(error: requests.exceptions.ConnectionError | requests.exceptions.Timeout) -> str:
348+
"""Return a concise message for a failed download connection."""
349+
request = getattr(error, "request", None)
350+
request_url = getattr(request, "url", "")
351+
host = urlparse(request_url).hostname or "the remote server"
352+
353+
if isinstance(error, requests.exceptions.Timeout):
354+
return f"Could not connect to {host}: the request timed out."
355+
356+
return (
357+
f"Could not connect to {host}. "
358+
"Check the server address and your network connection."
359+
)
360+
361+
347362
def _extract_checksums_from_jsonld(json_str: str) -> dict:
348363
"""
349364
Parse a JSON-LD string and return a mapping of file URI (and @id) -> checksum.

‎databusclient/cli.py‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
from typing import List
55

66
import click
7+
import requests
78

89
import databusclient.api.deploy as api_deploy
910
from databusclient.api.delete import delete as api_delete
10-
from databusclient.api.download import download as api_download, DownloadAuthError
11+
from databusclient.api.download import DownloadAuthError, download as api_download, format_download_connection_error
1112
from databusclient.manifest.context import ManifestContext
1213
from databusclient.manifest.writer import ManifestWriter
1314
from databusclient.manifest.replay import ManifestReplayError, replay_manifest, load_manifest
@@ -398,6 +399,10 @@ def download(
398399
if manifest_context:
399400
manifest_context.record_operation_error(e)
400401
raise click.ClickException(str(e))
402+
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as e:
403+
if manifest_context:
404+
manifest_context.record_operation_error(e)
405+
raise click.ClickException(format_download_connection_error(e))
401406
except ValueError as e:
402407
if manifest_context:
403408
manifest_context.record_operation_error(e)

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "databusclient"
3-
version = "1.2.0"
3+
version = "1.2.1"
44
description = "A simple client for submitting, downloading, and deleting data on the DBpedia Databus"
55
authors = ["DBpedia Association"]
66
license = "Apache-2.0 License"

‎tests/test_download.py‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import bz2
44

55
import pytest
6+
import requests
67
from click.testing import CliRunner
78

89
from databusclient.api.download import download as api_download
@@ -196,6 +197,46 @@ def fake_download(**kwargs):
196197
assert manifest["dbus:replayParams"]["graph_mode"] == "download-url"
197198

198199

200+
def test_cli_reports_redirected_download_timeout_without_traceback(monkeypatch):
201+
request = requests.Request(
202+
"HEAD", "https://data.dbpedia.org/repo/example/data.ttl"
203+
).prepare()
204+
205+
def timeout(**_kwargs):
206+
raise requests.exceptions.ConnectTimeout(request=request)
207+
208+
monkeypatch.setattr("databusclient.cli.api_download", timeout)
209+
210+
result = CliRunner().invoke(
211+
app, ["download", "https://databus.dbpedia.org/example/data.ttl"]
212+
)
213+
214+
assert result.exit_code == 1
215+
assert (
216+
"Error: Could not connect to data.dbpedia.org: "
217+
"the request timed out."
218+
) in result.output
219+
assert "Traceback" not in result.output
220+
221+
222+
def test_cli_reports_connection_failure_without_traceback(monkeypatch):
223+
request = requests.Request("GET", "https://files.example.org/data.ttl").prepare()
224+
225+
def connection_error(**_kwargs):
226+
raise requests.exceptions.ConnectionError(request=request)
227+
228+
monkeypatch.setattr("databusclient.cli.api_download", connection_error)
229+
230+
result = CliRunner().invoke(
231+
app, ["download", "https://databus.dbpedia.org/example/data.ttl"]
232+
)
233+
234+
assert result.exit_code == 1
235+
assert "Error: Could not connect to files.example.org." in result.output
236+
assert "Check the server address and your network connection." in result.output
237+
assert "Traceback" not in result.output
238+
239+
199240
def test_converted_output_gets_graph_sidecar_at_final_path(monkeypatch, tmp_path):
200241
import databusclient.api.download as dl
201242

0 commit comments

Comments
 (0)