我正在使用@Bean(name = "xmppConnection")
public XmppConnectionFactoryBean xmppConnectionFactoryBean() {
XmppConnectionFactoryBean connectionFactoryBean = new XmppConnectionFactoryBean();
connectionFactoryBean.setUser(senderId);
connectionFactoryBean.setPassword(apiKey);
connectionFactoryBean.setConnectionConfiguration(connectionConfiguration());
return connectionFactoryBean;
}
@Bean(name = "gcmChannel")
public MessageChannel messageChannel() {
return new DirectChannel();
}
@Bean
@ServiceActivator(inputChannel = "gcmChannel")
public MessageHandler messageHandler() {
return new ChatMessageSendingMessageHandler();
}
@Autowired
@Qualifier("gcmChannel")
private MessageChannel messageChannel;
进行一些http调用,并希望捕获任何异常并返回wreq
类型。我试过这样的事情,但无法弄清楚如何操纵调用,所以它会打字检查。
Either
我正在粘贴下面的类型错误,但我知道上面的代码无法编译。问题是 -- exhaustive pattern match omitted here
safeGetUrl :: URL -> Maybe Login -> Maybe Password -> IO (Either String (Response LBS.ByteString))
safeGetUrl url (Just login) (Just pass) = do
let def = defaults
opts = def & auth ?~ basicAuth (BS.pack login) (BS.pack pass)
r <- getWith opts url `E.catch` handler
return $ Right r
where
handler :: HttpException -> Either String (Response LBS.ByteString)
handler (StatusCodeException s _ _) = do
return $ Left $ LBS.unpack (s ^. statusMessage)
r <- getWith opts url
E.catch
。第一部分返回handler
但异常处理程序返回IO (Res...
。我尝试将Either..
添加到getWith..
中,但也没有输入。
Either
有没有办法捕获此异常并返回Couldn't match type ‘Either String (Response LBS.ByteString)’
with ‘IO (Response LBS.ByteString)’
Expected type: HttpException -> IO (Response LBS.ByteString)
Actual type: HttpException
-> Either String (Response LBS.ByteString)
In the second argument of ‘catch’, namely ‘handler’
In a stmt of a 'do' block: r <- getWith opts url `catch` handler
类型?
答案 0 :(得分:5)
自@jozefg回答以来,API已经改变了一点,答案就不再编译了。
这是一个编译的更新版本:
import qualified Control.Exception as E
import Control.Lens
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy as LBS
import Network.HTTP.Client
import Network.Wreq as NW
type URL = String
type Login = String
type Password = String
safeGetUrl ::
URL
-> Maybe Login
-> Maybe Password
-> IO (Either String (Response LBS.ByteString))
safeGetUrl url (Just login) (Just pass) = do
let def = defaults
opts = def & auth ?~ basicAuth (BSC.pack login) (BSC.pack pass)
(Right <$> getWith opts url) `E.catch` handler
where
handler :: HttpException -> IO (Either String (Response LBS.ByteString))
handler (HttpExceptionRequest _ (StatusCodeException r _)) =
return $ Left $ BSC.unpack (r ^. NW.responseStatus . statusMessage)
答案 1 :(得分:3)
您的问题是句柄的一侧返回一个未包装的响应(无Either
),另一侧返回Either
- 包装的异常。然后,您尝试将响应包装在Either
中,您需要这样做,但它只是在错误的位置。你可以通过切换包装的位置来解决这个问题
safeGetUrl :: URL -> Maybe Login -> Maybe Password -> IO (Either String (Response LBS.ByteString))
safeGetUrl url (Just login) (Just pass) = do
let def = defaults
opts = def & auth ?~ basicAuth (BS.pack login) (BS.pack pass)
(Right <$> getWith opts url) `E.catch` handler
where
handler :: HttpException -> IO (Either String (Response LBS.ByteString))
handler (StatusCodeException s _ _) = do
return $ Left $ LBS.unpack (s ^. statusMessage)
但是,您的功能存在其他一些问题,请记住unpack
回复Word8
而不是Char
。您可能希望导入Data.ByteString.Char
,因为其中定义的unpack
版本的效果应优于LBS.unpack
。没有你的进口虽然我无法确定这一点。我的最终(工作)代码是
import Control.Lens
import Network.Wreq
import Network.HTTP.Client
import qualified Control.Exception as E
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy as LBS
type URL = String
type Login = String
type Password = String
safeGetUrl :: URL
-> Maybe Login
-> Maybe Password
-> IO (Either String (Response LBS.ByteString))
safeGetUrl url (Just login) (Just pass) = do
let def = defaults
opts = def & auth ?~ basicAuth (BSC.pack login) (BSC.pack pass)
(Right <$> getWith opts url) `E.catch` handler
where
handler :: HttpException -> IO (Either String (Response LBS.ByteString))
handler (StatusCodeException s _ _) = do
return $ Left $ BSC.unpack (s ^. statusMessage)