{-|
Module      : Gargantext.Utils.Jobs.Error
Description : Error utilities
Copyright   : (c) CNRS, 2024
License     : AGPL + CECILL v3
Maintainer  : team@gargantext.org
Stability   : experimental
Portability : POSIX

-}

module Gargantext.Utils.Jobs.Error
  ( ToHumanFriendlyError(..)
  , HumanFriendlyErrorText(..)
  ) where

import Prelude
import Data.Void
import qualified Data.Text as T

-- | This class represents the concept of \"human friendly strings\", by which we mean
-- error messages and/or diagnostics which needs to be displayed to the end users, and, as such:
--
-- 1. They should be easy to understand for end users, not developers (developers would access
--    the full debug logs on the server machine). As such, they don't have to include implementation
--    details and/or technicalities;
-- 2. They /MUST NOT/ include any sensitive data. Please be very careful when writing these instances
--    because just calling \"T.pack . show\" on the input data is immediately wrong; things like Servant's
--    'ClientError' or any HTTP exception might include api keys in the form of HTTP headers, so leaking
--    that is /BAD/.
class ToHumanFriendlyError e where
  mkHumanFriendly :: e -> T.Text

-- | A newtype to wrap a 'Text' to be displayed to the end user.
-- /IMPORTANT/: You need to be very careful when using this newtype; please ensure that the text
-- you are wrapping with this newtype doesn't contain sentitive information.
newtype HumanFriendlyErrorText = UnsafeMkHumanFriendlyErrorText { _HumanFriendlyErrorText :: T.Text }
  deriving (Show, Eq, Ord)

instance ToHumanFriendlyError HumanFriendlyErrorText where
  mkHumanFriendly = _HumanFriendlyErrorText

-- /N.B/ Don't get fooled by this instance, it's just to help inference in case we use \"markFailed Nothing\".
instance ToHumanFriendlyError Void where
  mkHumanFriendly = absurd