Skip to content
Closed
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
23 changes: 20 additions & 3 deletions src/citrine/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,26 @@


class CitrineException(Exception):
"""The base exception class for Citrine-Python exceptions."""

pass
"""The base exception class for Citrine-Python exceptions.

Parameters
----------
*args
Positional arguments passed to the base Exception class.
hint : str, optional
An actionable suggestion for how the user can resolve
the error. Displayed after the main message.
"""

def __init__(self, *args, hint=None):
super().__init__(*args)
self.hint = hint

def __str__(self):
base = super().__str__()
if self.hint:
return "{}\n\nHint: {}".format(base, self.hint)
return base


class NonRetryableException(CitrineException):
Expand Down
49 changes: 49 additions & 0 deletions tests/test_exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""Tests for the Citrine exception hierarchy."""
import pytest

from citrine.exceptions import CitrineException


def test_citrine_exception_without_hint():
exc = CitrineException("something went wrong")
assert str(exc) == "something went wrong"
assert exc.hint is None


def test_citrine_exception_with_hint():
exc = CitrineException("bad request", hint="Check your input.")
assert "bad request" in str(exc)
assert "Hint: Check your input." in str(exc)
assert exc.hint == "Check your input."


def test_citrine_exception_hint_format():
exc = CitrineException("error", hint="Try again.")
expected = "error\n\nHint: Try again."
assert str(exc) == expected


def test_citrine_exception_no_args():
exc = CitrineException()
assert str(exc) == ""
assert exc.hint is None


def test_citrine_exception_no_args_with_hint():
exc = CitrineException(hint="Do something.")
assert "Hint: Do something." in str(exc)


def test_citrine_exception_is_catchable_as_exception():
with pytest.raises(Exception):
raise CitrineException("test")


def test_hint_preserved_through_subclass():
"""Subclasses that call super().__init__ with hint should work."""
class MyError(CitrineException):
pass

exc = MyError("oops", hint="Fix it.")
assert exc.hint == "Fix it."
assert "Hint: Fix it." in str(exc)
Loading