From 946781063214f5e4e4c18a531e48a00c57c1e431 Mon Sep 17 00:00:00 2001 From: knst-kotov Date: Sun, 1 Aug 2021 11:40:24 +0000 Subject: [PATCH] new api error handling --- resolvers/auth.py | 32 ++++++++++++++++++++++++-------- resolvers/base.py | 23 +++++++++++++++++++++-- schema.graphql | 26 ++++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 12 deletions(-) diff --git a/resolvers/auth.py b/resolvers/auth.py index 4c03e1a5..108846d1 100644 --- a/resolvers/auth.py +++ b/resolvers/auth.py @@ -7,7 +7,8 @@ from auth.password import Password from auth.validations import CreateUser from orm import User from orm.base import global_session -from resolvers.base import mutation, query +from resolvers.base import mutation, query, sign_in_result, register_user_result, ApiError +from exceptions import InvalidPassword from settings import JWT_AUTH_HEADER @@ -33,28 +34,45 @@ async def register(*_, email: str, password: str = ""): # TODO: sendAuthEmail(confirm_token) # без пароля не возвращаем, а высылаем токен на почту # - return { "status": True, "user": user } + return { "user": user } else: create_user.password = Password.encode(create_user.password) user = User.create(**create_user.dict()) token = await Authorize.authorize(user) - return {"status": True, "user": user, "token": token } + return {"user": user, "token": token } + +@register_user_result.type_resolver +def resolve_register_user_result(obj, *_): + if isinstance(obj, ApiError): + return "ApiError" + return "RegisterUserOk" @query.field("signIn") async def sign_in(_, info: GraphQLResolveInfo, email: str, password: str): orm_user = global_session.query(User).filter(User.email == email).first() if orm_user is None: - return {"status" : False, "error" : "invalid email"} + return ApiError("invalid email") try: device = info.context["request"].headers['device'] except KeyError: device = "pc" auto_delete = False if device == "mobile" else True # why autodelete with mobile? - user = Identity.identity(user_id=orm_user.id, password=password) + + try: + user = Identity.identity(user_id=orm_user.id, password=password) + except InvalidPassword: + return ApiError("invalid password") + token = await Authorize.authorize(user, device=device, auto_delete=auto_delete) - return {"status" : True, "token" : token, "user": user} + return {"token" : token, "user": user} + +@sign_in_result.type_resolver +def resolve_sign_in_result(obj, *_): + if isinstance(obj, ApiError): + return "ApiError" + return "SignInOk" @query.field("signOut") @@ -77,5 +95,3 @@ async def get_user(_, info): async def is_email_free(_, info, email): user = global_session.query(User).filter(User.email == email).first() return { "status": user is None } - - diff --git a/resolvers/base.py b/resolvers/base.py index 3175f99e..3f8c03f7 100644 --- a/resolvers/base.py +++ b/resolvers/base.py @@ -1,4 +1,5 @@ -from ariadne import MutationType, QueryType, SubscriptionType, ScalarType +from ariadne import MutationType, QueryType, SubscriptionType, ScalarType, InterfaceType, UnionType + query = QueryType() mutation = MutationType() @@ -12,4 +13,22 @@ def serialize_datetime(value): return value.isoformat() -resolvers = [query, mutation, subscription, datetime_scalar] +class ApiError: + def __init__(self, message): + self.message = message + +error_interface = InterfaceType("ErrorInterface") + +@error_interface.type_resolver +def resolve_search_result_type(obj, *_): + if isinstance(obj, ApiError): + return "ApiError" + + +sign_in_result = UnionType("SignInResult") +register_user_result = UnionType("RegisterUserResult") + +results = [sign_in_result, register_user_result] + +resolvers = [query, mutation, subscription, datetime_scalar, error_interface] +resolvers.extend(results) diff --git a/schema.graphql b/schema.graphql index bcb71caf..311fc34a 100644 --- a/schema.graphql +++ b/schema.graphql @@ -2,6 +2,28 @@ scalar DateTime ################################### Payload +interface ErrorInterface { + message: String! +} + +type ApiError implements ErrorInterface { + message: String! +} + +type SignInOk { + token: String! + user: User! +} + +union SignInResult = ApiError | SignInOk + +type RegisterUserOk { + token: String + user: User! +} + +union RegisterUserResult = ApiError | RegisterUserOk + type ResultPayload { status: Boolean! error: String @@ -26,7 +48,7 @@ type Mutation { # invalidateTokenById(id: Int!): Boolean! # requestEmailConfirmation: User! # requestPasswordReset(email: String!): Boolean! - registerUser(email: String!, password: String!): ResultPayload! + registerUser(email: String!, password: String!): RegisterUserResult! # shout createShout: ResultPayload! @@ -44,7 +66,7 @@ type Mutation { type Query { # auth / user isEmailFree(email: String!): ResultPayload! - signIn(email: String!, password: String!): ResultPayload! + signIn(email: String!, password: String!): SignInResult! signOut: ResultPayload! getCurrentUser: ResultPayload! # getUserById(id: Int!): ResultPayload!