Skip to content

Commit f7433d8

Browse files
author
Connor Brinton
committed
Don't suppress SQLAlchemy errors when mapping classes
1 parent 33d5b74 commit f7433d8

File tree

3 files changed

+49
-5
lines changed

3 files changed

+49
-5
lines changed

graphene_sqlalchemy/tests/test_types.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import six
55
from promise import Promise
66

7+
from .. import utils
78
from ..registry import Registry
89
from ..types import SQLAlchemyObjectType, SQLAlchemyObjectTypeOptions
910
from .models import Article, Reporter
@@ -181,3 +182,35 @@ class Meta:
181182
resolver, TestConnection, ReporterWithCustomOptions, None, None
182183
)
183184
assert result is not None
185+
186+
187+
def test_errors_propagated():
188+
# Get current `class_mapper` value
189+
old_class_mapper = utils.class_mapper
190+
191+
try:
192+
# Define unique error to detect
193+
class UniqueError(Exception):
194+
pass
195+
196+
# Redefine `class_mapper` in utils
197+
def new_class_mapper(*args, **kwargs):
198+
raise UniqueError()
199+
utils.class_mapper = new_class_mapper
200+
201+
# Make sure that errors are propagated from class_mapper when instantiating classes
202+
error = None
203+
try:
204+
class Tree(SQLAlchemyObjectType):
205+
class Meta(object):
206+
model = Article
207+
208+
except UniqueError as e:
209+
error = e
210+
211+
# Check that an error occured, and that it was a SQLAlchemy error
212+
assert error is not None
213+
assert isinstance(error, UniqueError)
214+
finally:
215+
# Restore original class mapper
216+
utils.class_mapper = old_class_mapper

graphene_sqlalchemy/types.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,11 @@ def __init_subclass_with_meta__(
103103
_meta=None,
104104
**options
105105
):
106-
assert is_mapped_class(model), (
107-
"You need to pass a valid SQLAlchemy Model in " '{}.Meta, received "{}".'
108-
).format(cls.__name__, model)
106+
# Make sure model is a valid SQLAlchemy model
107+
if not is_mapped_class(model):
108+
raise ValueError(
109+
"You need to pass a valid SQLAlchemy Model in " '{}.Meta, received "{}".'.format(cls.__name__, model)
110+
)
109111

110112
if not registry:
111113
registry = get_global_registry()

graphene_sqlalchemy/utils.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,17 @@ def get_query(model, context):
2525
def is_mapped_class(cls):
2626
try:
2727
class_mapper(cls)
28-
except (ArgumentError, UnmappedClassError):
29-
return False
28+
except (ArgumentError, UnmappedClassError) as error:
29+
# Only handle ArgumentErrors for non-class objects
30+
if isinstance(error, ArgumentError) and "Class object expected" in str(error):
31+
return False
32+
33+
# Unmapped classes return false
34+
if isinstance(error, UnmappedClassError):
35+
return False
36+
37+
# We don't know how to handle this type of error, reraise
38+
raise error
3039
else:
3140
return True
3241

0 commit comments

Comments
 (0)