String, tp: ErrorType) = HandledException( msg, additionalFields = Map("type" -> m.enumNode(tp.value, errorType.name)), addFieldsInExtensions = false, addFieldsInError = true ) val onException: PartialFunction[(ResultMarshaller, Throwable), HandledException] = { case (m, qa: QueryAnalysisError) => logger.warn(s"QueryAnalysisError occurred. msg = ${qa.getMessage}") handleException(m, qa.getMessage, ErrorType.BadRequest) case (m, se: SyntaxError) => logger.info(s"SyntaxError occurred. msg = ${se.getMessage()}") handleException(m, se.getMessage, ErrorType.BadRequest) case (m, ewr: ErrorWithResolver) => logger.error(s"ErrorWithResolver occurred. msg = ${ewr.getMessage}", ewr) handleException(m, ewr.getMessage, ErrorType.ServerError) case (m, AuthenticationError(msg)) => logger.info(s"AuthenticationError occurred. msg = ${msg}") handleException(m, msg, ErrorType.BadRequest) case (m, NotFoundException(msg)) => logger.info(s"NotFoundException occurred. msg = ${msg}") handleException(m, msg, ErrorType.BadRequest) case (m, t: Throwable) => logger.error(s"unknown server error occurred. msg = ${t.getMessage}", t) handleException(m, t.getMessage, ErrorType.ServerError) } val onViolation: PartialFunction[(ResultMarshaller, Violation), HandledException] = { case (m, v) => logger.warn(s"Violation error occurred. msg = ${v.errorMessage}") handleException(m, v.errorMessage, ErrorType.BadRequest) } val onUserFacingError : PartialFunction[(ResultMarshaller, UserFacingError), HandledException] = { case (m, v: WithViolations) => logger.warn(s"WithViolations occurred. msg = ${v.getMessage()}") handleException(m, v.getMessage, ErrorType.BadRequest) case (m, ie: InternalError) => logger.error(s"InternalError occurred. msg = ${ie.getMessage()}", ie) handleException(m, ie.getMessage, ErrorType.ServerError) case (m, ee: ExecutionError) => logger.error(s"ExecutionError occurred. msg = ${ee.getMessage()}", ee) handleException(m, ee.getMessage, ErrorType.ServerError) case (m, ufe) => logger.warn(s"UserFacingError occurred. msg = ${ufe.getMessage()}") handleException(m, ufe.getMessage, ErrorType.BadRequest) } ExceptionHandler(onException, onViolation, onUserFacingError) } Future.fromTry(QueryParser.parse(document)) zip GraphQLContext.create(userIdOpt) flatMap { case (queryDocument: Document, context: GraphQLContext) => val result: Future[JsValue] = Executor.execute[Ctx, Unit, JsObject]( schema, queryDocument, context, exceptionHandler = exceptionHandler, operationName = operation, variables = vars, middleware = Middlewares.value ) result .map { jsValue => OK -> jsValue } .recover { case error: QueryAnalysisError => BadRequest -> error.resolveError case error: ErrorWithResolver => InternalServerError -> error.resolveError } } recover { case v: SyntaxError => BadRequest -> new Exception(v.getMessage()) with ErrorWithResolver with WithViolations { override def exceptionHandler: ExceptionHandler = GraphQLServer.exceptionHandler override def violations: Vector[Violation] = Vector.empty }.resolveError case v: ValidationError => BadRequest -> v.resolveError case NonFatal(t) => InternalServerError -> InternalError(t, GraphQLServer.exceptionHandler).resolveError } Δ͔͠ͳ͍ 120