Слуга печати исключений - PullRequest
       21

Слуга печати исключений

0 голосов
/ 11 апреля 2020

Как мне распечатать описание всех исключений? Было бы здорово переключить формат отладки / выпуска.

Стандартная установка Servant показывает только 500/Something went wrong, что не очень полезно

HTTP/1.1 500 Internal Server Error

Something went wrong

Upd:

I получите следующую ошибку, сообщающую о моем первом обработчике:

Server.hs:152:31: error:
    • No instance for (MonadCatch
                         ((:<|>) (Servant.Handler (Map.Map String String))))
        arising from a use of ‘catch’
    • In the expression:
        server `catch` (\ e -> handleExceptions (e :: SomeException))
      In an equation for ‘serverWithExceptionsHandled’:
          serverWithExceptionsHandled
            = server `catch` (\ e -> handleExceptions (e :: SomeException))

Сам обработчик:

type API = "ping" :> Get '[JSON] (Map.Map String String) ...

ping :: Servant.Handler (Map.Map String String)
ping = return $ Map.fromList [("reply", "pong")] 

Обновление:

server :: Server API
server = ping
    :<|> signup
    :<|> singin
    :<|> account
    :<|> getSessions


serverWithExceptionsHandled = server `catch` (\e -> handleExceptions (e :: SomeException))

-- | print to console and then rethrow
handleExceptions :: (MonadIO m, MonadThrow m, Exception e) => e -> m b
handleExceptions e = do
  liftIO $ print e
  throwM e

app :: Application
app = serveWithContext api ctx serverWithExceptionsHandled
        where ctx = checkBasicAuth :. EmptyContext

1 Ответ

2 голосов
/ 11 апреля 2020

Весь код сервера выполняется в Handler, который имеет экземпляр MonadCatch, а также экземпляр MonadThrow. Таким образом, вы можете деформировать свой серверный код с помощью обработчиков исключений, например:

handled :: Server SomeRoute
handled = server1 `catch` (\e -> handleExceptions (e :: SomeException))

type API = SomeRoute :<|> (other routes)

combined :: Server API
combined = handled :<|> (server code for other routes)

app :: Application
app = serve @API Proxy combined

, где handleExceptions - ваш обработчик исключений, например:

-- | print to console and then rethrow
handleExceptions e = do
  liftIO $ print e
  throwM e

другие примеры:

ping' = ping `catch` (\e -> handleExceptions (e :: SomeException))

server :: Server API
server = ping'
    :<|> signup
    :<|> singin
    :<|> account
    :<|> getSessions
...