handleTokenRefresh :: (Manager -> HTTP.AccessToken -> ResourceT IO a) -> HTTP.AccessToken -> Manager -> ResourceT IO a
handleTokenRefresh accessFunc token manager = catch (accessFunc manager token) handleException
    where
        handleException e@(HttpExceptionRequest _ (StatusCodeException response _)) =
            let
                status = responseStatus response
            in
                if status == status403 then
                    do
                        newToken <- liftIO $ refreshAccessToken manager token --TODO: exceptions?
                        liftIO $ storeAccessToken newToken
                        accessFunc manager newToken  --TODO: retry count??
                else if status == status401 then throw NotAuthenticated
                else throw $ HttpFailed e
        handleException e = throw $ HttpFailed e
handleTokenRefresh :: (Manager -> HTTP.AccessToken -> ResourceT IO a) -> HTTP.AccessToken -> Manager -> ResourceT IO a
handleTokenRefresh accessFunc token manager = catch (accessFunc manager token) handleException
    where
        handleException e@(HttpExceptionRequest _ (StatusCodeException response _)) =
            let
                status = responseStatus response
            in
                if status == status403 then
                    do
                        newToken <- liftIO $ refreshAccessToken manager token --TODO: exceptions?
                        liftIO $ storeAccessToken newToken
                        accessFunc manager newToken  --TODO: retry count??
                else if status == status401 then throw NotAuthenticated
                else throw $ HttpFailed e
        handleException e = throw $ HttpFailed e
handleTokenRefresh accessFunc token manager = catch (accessFunc manager token) handleException
    where
        handleException e@(HttpExceptionRequest _ (StatusCodeException response _)) =
            let
                status = responseStatus response
            in
                if status == status403 then
                    do
                        newToken <- liftIO $ refreshAccessToken manager token --TODO: exceptions?
                        liftIO $ storeAccessToken newToken
                        accessFunc manager newToken  --TODO: retry count??
                else if status == status401 then throw NotAuthenticated
                else throw $ HttpFailed e
        handleException e = throw $ HttpFailed e