-
Notifications
You must be signed in to change notification settings - Fork 3
/
EvalFailure.scala
93 lines (86 loc) · 2.66 KB
/
EvalFailure.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
* Copyright 2022 Valdemar Grange
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package gql.interpreter
import io.circe.syntax._
import io.circe._
import cats.data._
import cats.implicits._
sealed trait EvalFailure {
def paths: Chain[Cursor]
def exception: Option[Throwable]
def asGraphQL: Chain[JsonObject] = {
final case class GQLError(
message: String,
path: Cursor
)
def formatEither(e: Either[Throwable, String]) =
e.swap.as("internal error").merge
import EvalFailure._
val errors =
this match {
case EffectResolution(path, error, _) =>
Chain(GQLError(formatEither(error), path))
case BatchResolution(paths, _, _) =>
paths.map(path => GQLError("internal error", path))
case StreamHeadResolution(path, err, _) =>
Chain(GQLError(formatEither(err), path))
case StreamTailResolution(path, err) =>
Chain(GQLError(formatEither(err), path))
}
errors.map { err =>
JsonObject(
"message" -> Json.fromString(err.message),
"path" -> err.path.path.map {
case GraphArc.Field(_, name) => Json.fromString(name)
case GraphArc.Index(idx) => Json.fromInt(idx)
case GraphArc.Fragment(_, name) => Json.fromString(s"fragment:$name")
}.asJson
)
}
}
}
object EvalFailure {
final case class StreamHeadResolution(
path: Cursor,
error: Either[Throwable, String],
input: Any
) extends EvalFailure {
lazy val paths = Chain(path)
lazy val exception = error.swap.toOption
}
final case class StreamTailResolution(
path: Cursor,
error: Either[Throwable, String]
) extends EvalFailure {
lazy val paths = Chain(path)
lazy val exception = error.swap.toOption
}
final case class BatchResolution(
paths: Chain[Cursor],
ex: Throwable,
keys: Set[Any]
) extends EvalFailure {
lazy val exception = Some(ex)
}
final case class EffectResolution(
path: Cursor,
error: Either[Throwable, String],
input: Any
) extends EvalFailure {
lazy val paths = Chain(path)
lazy val exception = error.swap.toOption
}
}