Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
haskell-gargantext
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
160
Issues
160
List
Board
Labels
Milestones
Merge Requests
14
Merge Requests
14
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
haskell-gargantext
Commits
3bac6a59
Commit
3bac6a59
authored
Oct 23, 2023
by
Alfredo Di Napoli
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Introduce the FrontendError type
parent
958fe77f
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
112 additions
and
12 deletions
+112
-12
Errors.hs
src/Gargantext/API/Errors.hs
+108
-10
JSON.hs
test/Test/Offline/JSON.hs
+4
-2
No files found.
src/Gargantext/API/Errors.hs
View file @
3bac6a59
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE RecordWildCards #-}
module
Gargantext.API.Errors
where
...
...
@@ -5,6 +16,13 @@ import Prelude
import
GHC.Stack
import
Control.Exception
import
qualified
Data.Text
as
T
import
Data.Kind
import
Data.Singletons.TH
import
qualified
Network.HTTP.Types
as
HTTP
import
Test.QuickCheck
import
Test.QuickCheck.Instances.Text
()
import
Data.Aeson
as
JSON
import
GHC.Generics
-- | A 'WithStacktrace' carries an error alongside its
-- 'CallStack', to be able to print the correct source location
...
...
@@ -19,18 +37,98 @@ instance Exception e => Exception (WithStacktrace e) where
displayException
WithStacktrace
{
..
}
=
displayException
ct_error
<>
"
\n
"
<>
prettyCallStack
ct_callStack
-- | An error that can be returned to the frontend. It carries a human-friendly
-- diagnostic, the 'type' of the error as well as some context-specific data.
data
FrontendError
a
=
FrontendError
{
fe_diagnostic
::
!
T
.
Text
,
fe_type
::
!
BackendErrorType
,
fe_data
::
Maybe
a
}
deriving
(
Show
,
Eq
)
-- | A (hopefully and eventually) exhaustive list of backend errors.
data
BackendErrorType
=
BE_phylo_corpus_not_ready
|
BE_not_good_enough_ratio
|
BE_node_not_found
deriving
(
Show
,
Eq
)
deriving
(
Show
,
Eq
,
Enum
,
Bounded
)
$
(
genSingletons
[
''
B
ackendErrorType
])
-- | An error that can be returned to the frontend. It carries a human-friendly
-- diagnostic, the 'type' of the error as well as some context-specific data.
data
FrontendError
where
FrontendError
::
forall
b
.
(
IsFrontendErrorData
b
)
=>
{
fe_diagnostic
::
!
T
.
Text
,
fe_type
::
!
BackendErrorType
,
fe_data
::
ToFrontendErrorData
b
}
->
FrontendError
deriving
instance
Show
FrontendError
class
(
SingI
payload
,
ToJSON
(
ToFrontendErrorData
payload
)
-- , FromJSON (ToFrontendErrorData payload)
,
Show
(
ToFrontendErrorData
payload
)
)
=>
IsFrontendErrorData
payload
instance
IsFrontendErrorData
'B
E
_phylo_corpus_not_ready
instance
IsFrontendErrorData
'B
E
_not_good_enough_ratio
instance
IsFrontendErrorData
'B
E
_node_not_found
data
family
ToFrontendErrorData
(
payload
::
BackendErrorType
)
::
Type
data
instance
ToFrontendErrorData
'B
E
_phylo_corpus_not_ready
=
PhyloCorpusNotReady
deriving
(
Show
,
Generic
)
data
instance
ToFrontendErrorData
'B
E
_not_good_enough_ratio
=
NotGoodEnoughRatio
deriving
(
Show
,
Generic
)
data
instance
ToFrontendErrorData
'B
E
_node_not_found
=
NodeNotFound
deriving
(
Show
,
Generic
)
instance
ToJSON
(
ToFrontendErrorData
'B
E
_phylo_corpus_not_ready
)
instance
ToJSON
(
ToFrontendErrorData
'B
E
_not_good_enough_ratio
)
instance
ToJSON
(
ToFrontendErrorData
'B
E
_node_not_found
)
mkFrontendErr
::
IsFrontendErrorData
payload
=>
Proxy
(
payload
::
BackendErrorType
)
->
ToFrontendErrorData
payload
->
FrontendError
mkFrontendErr
et
=
mkFrontendErr'
mempty
et
mkFrontendErr'
::
IsFrontendErrorData
payload
=>
T
.
Text
->
Proxy
(
payload
::
BackendErrorType
)
->
ToFrontendErrorData
payload
->
FrontendError
mkFrontendErr'
diag
(
Proxy
::
Proxy
payload
)
pl
=
FrontendError
diag
(
fromSing
$
sing
@
payload
)
pl
instance
Arbitrary
BackendErrorType
where
arbitrary
=
arbitraryBoundedEnum
backendErrorTypeToErrStatus
::
BackendErrorType
->
HTTP
.
Status
backendErrorTypeToErrStatus
=
\
case
BE_phylo_corpus_not_ready
->
HTTP
.
status500
BE_not_good_enough_ratio
->
HTTP
.
status500
BE_node_not_found
->
HTTP
.
status500
instance
Arbitrary
FrontendError
where
arbitrary
=
do
et
<-
arbitrary
txt
<-
arbitrary
genFrontendErr
txt
et
genFrontendErr
::
T
.
Text
->
BackendErrorType
->
Gen
FrontendError
genFrontendErr
txt
be
=
case
be
of
BE_phylo_corpus_not_ready
->
pure
$
mkFrontendErr'
txt
(
Proxy
@
'B
E
_phylo_corpus_not_ready
)
PhyloCorpusNotReady
BE_not_good_enough_ratio
->
pure
$
mkFrontendErr'
txt
(
Proxy
@
'B
E
_not_good_enough_ratio
)
NotGoodEnoughRatio
BE_node_not_found
->
pure
$
mkFrontendErr'
txt
(
Proxy
@
'B
E
_node_not_found
)
NodeNotFound
-- | This compiles if we use the correct payload type, or otherwise it won't:
-- >>> mkFrontendErr (Proxy @'BE_phylo_corpus_not_ready) NodeNotFound
myTest
::
FrontendError
myTest
=
mkFrontendErr
(
Proxy
@
'B
E
_phylo_corpus_not_ready
)
PhyloCorpusNotReady
instance
ToJSON
BackendErrorType
where
toJSON
=
\
case
BE_phylo_corpus_not_ready
->
JSON
.
String
"phylo_corpus_not_ready"
BE_not_good_enough_ratio
->
JSON
.
String
"not_good_enough_ratio"
BE_node_not_found
->
JSON
.
String
"node_not_found"
instance
ToJSON
FrontendError
where
toJSON
fe
=
JSON
.
object
[
"diagnostic"
.=
toJSON
(
fe_diagnostic
fe
)
,
"type"
.=
toJSON
(
fe_type
fe
)
,
"data"
.=
case
fe
of
(
FrontendError
_
_
dt
)
->
toJSON
dt
]
test/Test/Offline/JSON.hs
View file @
3bac6a59
...
...
@@ -7,6 +7,7 @@ module Test.Offline.JSON (tests) where
import
Data.Aeson
import
Data.Either
import
Gargantext.API.Errors
import
Gargantext.API.Node.Corpus.New
import
Gargantext.API.Node.Corpus.Types
import
Gargantext.Core.Types.Phylo
...
...
@@ -29,6 +30,7 @@ tests :: TestTree
tests
=
testGroup
"JSON"
[
testProperty
"Datafield roundtrips"
(
jsonRoundtrip
@
Datafield
)
,
testProperty
"WithQuery roundtrips"
(
jsonRoundtrip
@
WithQuery
)
,
testProperty
"FrontendError roundtrips"
(
jsonRoundtrip
@
FrontendError
)
,
testCase
"WithQuery frontend compliance"
testWithQueryFrontend
,
testGroup
"Phylo"
[
testProperty
"PeriodToNode"
(
jsonRoundtrip
@
PeriodToNodeData
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment