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
1573c5f3
Commit
1573c5f3
authored
Nov 02, 2023
by
Alfredo Di Napoli
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Auto-derive IsFrontendErrorData
parent
5e210c11
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
82 additions
and
56 deletions
+82
-56
gargantext.cabal
gargantext.cabal
+1
-0
TH.hs
src/Gargantext/API/Errors/TH.hs
+16
-2
Types.hs
src/Gargantext/API/Errors/Types.hs
+25
-54
Backend.hs
src/Gargantext/API/Errors/Types/Backend.hs
+40
-0
No files found.
gargantext.cabal
View file @
1573c5f3
...
...
@@ -55,6 +55,7 @@ library
Gargantext.API.Errors.Class
Gargantext.API.Errors.TH
Gargantext.API.Errors.Types
Gargantext.API.Errors.Types.Backend
Gargantext.API.HashedResponse
Gargantext.API.Ngrams
Gargantext.API.Ngrams.Prelude
...
...
src/Gargantext/API/Errors/TH.hs
View file @
1573c5f3
...
...
@@ -3,16 +3,17 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module
Gargantext.API.Errors.TH
(
deriveHttpStatusCode
deriveHttpStatusCode
,
deriveIsFrontendErrorData
)
where
import
Prelude
import
Gargantext.API.Errors.Types.Backend
import
Network.HTTP.Types
import
qualified
Data.Map.Strict
as
Map
import
qualified
Data.Text
as
T
import
qualified
Language.Haskell.TH
as
TH
import
Gargantext.API.Errors.Types
import
qualified
Network.HTTP.Types
as
HTTP
-- | A static map of the HTTP status code we support.
...
...
@@ -72,3 +73,16 @@ parse_error_codes = mapM go
Just
st
->
Right
(
n
,
st
,
msg
)
where
(
code
,
msg
)
=
do_parse
$
(
T
.
pack
$
TH
.
nameBase
n
)
deriveIsFrontendErrorData
::
TH
.
Name
->
TH
.
Q
[
TH
.
Dec
]
deriveIsFrontendErrorData
appliedType
=
do
info
<-
TH
.
reify
appliedType
case
info
of
TH
.
TyConI
(
TH
.
DataD
_
_
_
_
ctors
_
)
->
case
extract_names
ctors
of
Left
ctor
->
error
$
"Only enum-like constructors supported: "
++
show
ctor
Right
names
->
fmap
mconcat
.
sequence
$
flip
map
names
$
\
n
->
[
d
|
instance IsFrontendErrorData $(TH.promotedT n) where
isFrontendErrorData _ = Dict
|]
err
->
error
$
"Cannot call deriveHttpStatusCode on: "
++
show
err
src/Gargantext/API/Errors/Types.hs
View file @
1573c5f3
...
...
@@ -11,10 +11,11 @@
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# OPTIONS_GHC -Wno-unused-top-binds #-}
{-# OPTIONS_GHC -Wno-orphans #-}
-- instance IsFrontendErrorData and stage restriction
module
Gargantext.API.Errors.Types
(
-- * The main frontend error type
FrontendError
(
..
)
FrontendError
(
..
)
-- * The internal backend type and an enumeration of all possible backend error types
,
BackendErrorCode
(
..
)
...
...
@@ -41,13 +42,14 @@ import Control.Exception
import
Control.Lens
(
makePrisms
)
import
Data.Aeson
as
JSON
import
Data.Aeson.Types
(
typeMismatch
,
emptyArray
)
import
Data.Kind
import
Data.Singletons.TH
import
Data.Typeable
import
Data.Validity
(
Validation
)
import
GHC.Generics
import
GHC.Stack
import
Gargantext.API.Errors.Class
import
Gargantext.API.Errors.TH
import
Gargantext.API.Errors.Types.Backend
import
Gargantext.Core.Types
(
HasValidationError
(
..
))
import
Gargantext.Database.Admin.Types.Node
import
Gargantext.Database.Query.Table.Node.Error
...
...
@@ -120,19 +122,6 @@ instance HasServerError BackendInternalError where
instance
HasJoseError
BackendInternalError
where
_JoseError
=
_InternalJoseError
-- | A (hopefully and eventually) exhaustive list of backend errors.
data
BackendErrorCode
=
-- node errors
EC_404__node_error_list_not_found
|
EC_404__node_error_root_not_found
|
EC_404__node_error_corpus_not_found
-- tree errors
|
EC_404__tree_error_root_not_found
deriving
(
Show
,
Read
,
Eq
,
Enum
,
Bounded
)
$
(
genSingletons
[
''
B
ackendErrorCode
])
-- | 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
...
...
@@ -142,6 +131,25 @@ data FrontendError where
,
fe_data
::
ToFrontendErrorData
b
}
->
FrontendError
-- | Creates an error without attaching a diagnostic to it.
mkFrontendErrNoDiagnostic
::
IsFrontendErrorData
payload
=>
ToFrontendErrorData
payload
->
FrontendError
mkFrontendErrNoDiagnostic
et
=
mkFrontendErr'
mempty
et
-- | Renders the error by using as a diagnostic the string
-- resulting from 'Show'ing the underlying type.
mkFrontendErrShow
::
IsFrontendErrorData
payload
=>
ToFrontendErrorData
payload
->
FrontendError
mkFrontendErrShow
et
=
mkFrontendErr'
(
T
.
pack
$
show
et
)
et
mkFrontendErr'
::
forall
payload
.
IsFrontendErrorData
payload
=>
T
.
Text
->
ToFrontendErrorData
(
payload
::
BackendErrorCode
)
->
FrontendError
mkFrontendErr'
diag
pl
=
FrontendError
diag
(
fromSing
$
sing
@
payload
)
pl
deriving
instance
Show
FrontendError
instance
Eq
FrontendError
where
f1
==
f2
=
case
(
f1
,
f2
)
of
...
...
@@ -152,32 +160,14 @@ instance Eq FrontendError where
Nothing
->
False
Just
Refl
->
fe_data_1
==
fe_data_2
class
(
SingI
payload
,
ToJSON
(
ToFrontendErrorData
payload
)
,
FromJSON
(
ToFrontendErrorData
payload
)
,
Show
(
ToFrontendErrorData
payload
)
,
Eq
(
ToFrontendErrorData
payload
)
,
Typeable
payload
)
=>
IsFrontendErrorData
payload
where
isFrontendErrorData
::
Proxy
payload
->
Dict
IsFrontendErrorData
payload
instance
IsFrontendErrorData
'E
C
_404__node_error_list_not_found
where
isFrontendErrorData
_
=
Dict
instance
IsFrontendErrorData
'E
C
_404__node_error_root_not_found
where
isFrontendErrorData
_
=
Dict
instance
IsFrontendErrorData
'E
C
_404__node_error_corpus_not_found
where
isFrontendErrorData
_
=
Dict
instance
IsFrontendErrorData
'E
C
_404__tree_error_root_not_found
where
isFrontendErrorData
_
=
Dict
$
(
deriveIsFrontendErrorData
''
B
ackendErrorCode
)
----------------------------------------------------------------------------
-- T
his data family maps a 'BackendErrorCode' into a concrete payload.
-- T
oFrontendErrorData data family instances
----------------------------------------------------------------------------
data
NoFrontendErrorData
=
NoFrontendErrorData
data
family
ToFrontendErrorData
(
payload
::
BackendErrorCode
)
::
Type
newtype
instance
ToFrontendErrorData
'E
C
_404__node_error_list_not_found
=
FE_node_error_list_not_found
{
lnf_list_id
::
ListId
}
deriving
(
Show
,
Eq
,
Generic
)
...
...
@@ -227,25 +217,6 @@ instance FromJSON (ToFrontendErrorData 'EC_404__tree_error_root_not_found) where
_rnf_rootId
<-
o
.:
"root_id"
pure
RootNotFound
{
..
}
-- | Creates an error without attaching a diagnostic to it.
mkFrontendErrNoDiagnostic
::
IsFrontendErrorData
payload
=>
ToFrontendErrorData
payload
->
FrontendError
mkFrontendErrNoDiagnostic
et
=
mkFrontendErr'
mempty
et
-- | Renders the error by using as a diagnostic the string
-- resulting from 'Show'ing the underlying type.
mkFrontendErrShow
::
IsFrontendErrorData
payload
=>
ToFrontendErrorData
payload
->
FrontendError
mkFrontendErrShow
et
=
mkFrontendErr'
(
T
.
pack
$
show
et
)
et
mkFrontendErr'
::
forall
payload
.
IsFrontendErrorData
payload
=>
T
.
Text
->
ToFrontendErrorData
(
payload
::
BackendErrorCode
)
->
FrontendError
mkFrontendErr'
diag
pl
=
FrontendError
diag
(
fromSing
$
sing
@
payload
)
pl
----------------------------------------------------------------------------
-- Arbitrary instances and test data generation
----------------------------------------------------------------------------
...
...
src/Gargantext/API/Errors/Types/Backend.hs
0 → 100644
View file @
1573c5f3
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
module
Gargantext.API.Errors.Types.Backend
where
import
Data.Aeson
import
Data.Kind
import
Data.Singletons.TH
import
Data.Typeable
import
Gargantext.Utils.Dict
import
Prelude
-- | A (hopefully and eventually) exhaustive list of backend errors.
data
BackendErrorCode
=
-- node errors
EC_404__node_error_list_not_found
|
EC_404__node_error_root_not_found
|
EC_404__node_error_corpus_not_found
-- tree errors
|
EC_404__tree_error_root_not_found
deriving
(
Show
,
Read
,
Eq
,
Enum
,
Bounded
)
$
(
genSingletons
[
''
B
ackendErrorCode
])
----------------------------------------------------------------------------
-- This data family maps a 'BackendErrorCode' into a concrete payload.
----------------------------------------------------------------------------
data
family
ToFrontendErrorData
(
payload
::
BackendErrorCode
)
::
Type
class
(
SingI
payload
,
ToJSON
(
ToFrontendErrorData
payload
)
,
FromJSON
(
ToFrontendErrorData
payload
)
,
Show
(
ToFrontendErrorData
payload
)
,
Eq
(
ToFrontendErrorData
payload
)
,
Typeable
payload
)
=>
IsFrontendErrorData
payload
where
isFrontendErrorData
::
Proxy
payload
->
Dict
IsFrontendErrorData
payload
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