【发布时间】:2019-05-09 09:53:27
【问题描述】:
我正在用 Ruby(没有 Rails)在 REST-API 和 SOAP API 之间建立连接。 对于 SOAP 调用,我使用 Savon gem,这很棒。
但是,我无法从docs 中弄清楚,Savon 是如何处理Timeout::Error 的?
它会引发Savon::HTTPError 或Savon::SOAPFault 吗?
请指教。
【问题讨论】:
我正在用 Ruby(没有 Rails)在 REST-API 和 SOAP API 之间建立连接。 对于 SOAP 调用,我使用 Savon gem,这很棒。
但是,我无法从docs 中弄清楚,Savon 是如何处理Timeout::Error 的?
它会引发Savon::HTTPError 或Savon::SOAPFault 吗?
请指教。
【问题讨论】:
我自己也很好奇。经过一些实验和浏览 Savon 源代码后,似乎传输级错误没有被处理并转换为 Savon 自己的异常类型,而是“按原样”抛出,所以如果你需要处理它们,你必须处理抛出的异常通过底层 HTTP 客户端库。
需要注意的是,Savon 通过httpi 抽象层支持多个 HTTP 客户端。默认情况下,它只是从可用的那些中选择一个,但如果你需要处理它的异常,你不应该依赖自动选择,而是明确配置应该使用哪个 HTTPI 适配器(例如HTTPI.adapter = :net_http)。
下面的代码可用于使用您选择的 HTTPI 适配器测试超时场景。
实验代码
服务器(用 PHP 编写,因为there are no up-to-date working solutions for writing a dead-simple SOAP server like this, without a ton of boilerplate code, in Ruby):
<?php
// simple SOAP server - run with 'php -S localhost:12312 name_of_this_file.php'
class SleepySoapServer
{
public function hello()
{
sleep(3600); // take an hour's nap before responding
return 'Hello, world!';
}
}
$options = array('uri' => 'http://localhost:12312/');
$server = new SoapServer(null, $options);
$server->setClass(SleepySoapServer::class);
$server->handle();
客户端(使用 Savon 2):
require 'savon'
HTTPI.adapter = :net_http # request Net::HTTP client from the standard library
uri = 'http://localhost:12312'
client = Savon.client do
endpoint uri
namespace uri
end
response = client.call :Hello
p response.body
【讨论】:
Savon::HTTPError。所以,我决定将超时处理为 Savon::HTTPError。
savon (2.12.0) akami (~> 1.2) builder (>= 2.1.2) gyoku (~> 1.2) httpi (~> 2.3) nokogiri (>= 1.8.1) nori (~> 2.4) wasabi (~> 3.4)
如果您不喜欢挽救错误,可以通过以下方法告诉 Savon 不要提出错误
Savon.configure do |config|
config.raise_errors = false
end
【讨论】: