wreq 1.2.7 → 1.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Cargo.lock +1 -1
- data/Cargo.toml +1 -1
- data/lib/wreq_ruby/error.rb +4 -0
- data/src/client/body/stream.rs +1 -1
- data/src/error.rs +13 -2
- data/src/rt.rs +1 -1
- data/test/error_handling_test.rb +54 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 556005991e7cd3da728dada73a12c7fc016fa08e0701f7bc027e3da8c40003fd
|
|
4
|
+
data.tar.gz: dea7a13e0c20655b7aee8404e51c60c37b293c18bf453eac304e0bd9b9759f78
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c3f420c02de369f78abed9022089a2e221a8b5da7e71775aadce38cc23482615ba51405f447e855422f68f27b13af8534011816e0065eac42954bba1d1b8ce7a
|
|
7
|
+
data.tar.gz: 84876653e4a2233f2d0502b4eb3118a318178051b0dc52669aa26b94d85f741b23cff1f520d30c5891a32f630736adcd0c97dbd308e8530985234c5c017ea3a8
|
data/Cargo.lock
CHANGED
data/Cargo.toml
CHANGED
data/lib/wreq_ruby/error.rb
CHANGED
data/src/client/body/stream.rs
CHANGED
|
@@ -113,7 +113,7 @@ impl BodySender {
|
|
|
113
113
|
/// # Errors
|
|
114
114
|
///
|
|
115
115
|
/// Returns `IOError` after either channel side has closed. An interrupted
|
|
116
|
-
/// wait raises
|
|
116
|
+
/// wait raises `Wreq::InterruptError`.
|
|
117
117
|
pub fn push(ruby: &Ruby, rb_self: &Self, data: RString) -> Result<(), Error> {
|
|
118
118
|
// Clone during the shared borrow, then release it before waiting
|
|
119
119
|
// for capacity. Request attachment needs a mutable borrow.
|
data/src/error.rs
CHANGED
|
@@ -84,14 +84,18 @@ define_exception!(DECODING_ERROR, "DecodingError", exception_runtime_error);
|
|
|
84
84
|
// Configuration and builder errors
|
|
85
85
|
define_exception!(BUILDER_ERROR, "BuilderError", exception_runtime_error);
|
|
86
86
|
|
|
87
|
+
// Keep interruption outside StandardError so a broad transport rescue
|
|
88
|
+
// never swallows a Ruby interrupt.
|
|
89
|
+
define_exception!(INTERRUPT_ERROR, "InterruptError", exception_interrupt);
|
|
90
|
+
|
|
87
91
|
/// Memory error constant
|
|
88
92
|
pub fn memory_error(ruby: &Ruby) -> MagnusError {
|
|
89
93
|
MagnusError::new(ruby.get_inner(&MEMORY), RACE_CONDITION_ERROR_MSG)
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
/// Create Ruby
|
|
96
|
+
/// Create a `Wreq::InterruptError` when Ruby interrupts a request.
|
|
93
97
|
pub fn interrupt_error(ruby: &Ruby) -> MagnusError {
|
|
94
|
-
MagnusError::new(ruby.
|
|
98
|
+
MagnusError::new(ruby.get_inner(&INTERRUPT_ERROR), "request interrupted")
|
|
95
99
|
}
|
|
96
100
|
|
|
97
101
|
/// Map a Tokio runtime initialization failure to `Wreq::BuilderError`.
|
|
@@ -312,5 +316,12 @@ pub fn include(ruby: &Ruby, gem_module: &RModule) -> Result<(), MagnusError> {
|
|
|
312
316
|
"BuilderError",
|
|
313
317
|
exception_runtime_error
|
|
314
318
|
);
|
|
319
|
+
initialize_exception!(
|
|
320
|
+
ruby,
|
|
321
|
+
gem_module,
|
|
322
|
+
INTERRUPT_ERROR,
|
|
323
|
+
"InterruptError",
|
|
324
|
+
exception_interrupt
|
|
325
|
+
);
|
|
315
326
|
Ok(())
|
|
316
327
|
}
|
data/src/rt.rs
CHANGED
|
@@ -29,7 +29,7 @@ enum BlockOnError<E> {
|
|
|
29
29
|
/// # Errors
|
|
30
30
|
///
|
|
31
31
|
/// Returns `Wreq::BuilderError` if the Tokio runtime cannot be initialized,
|
|
32
|
-
///
|
|
32
|
+
/// `Wreq::InterruptError` if Ruby interrupts the request, or the error produced
|
|
33
33
|
/// by `map_err` if the future fails.
|
|
34
34
|
pub fn try_block_on<F, T, E, M>(ruby: &Ruby, future: F, map_err: M) -> Result<T, magnus::Error>
|
|
35
35
|
where
|
data/test/error_handling_test.rb
CHANGED
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
require "test_helper"
|
|
2
|
+
require "socket"
|
|
3
|
+
require "timeout"
|
|
2
4
|
|
|
3
5
|
class ErrorHandlingTest < Minitest::Test
|
|
6
|
+
def test_interrupt_error_stays_outside_standard_error
|
|
7
|
+
assert_equal Interrupt, Wreq::InterruptError.superclass
|
|
8
|
+
refute_operator Wreq::InterruptError, :<, StandardError
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_request_interruption_raises_interrupt_error
|
|
12
|
+
request_thread = nil
|
|
13
|
+
with_hanging_server do |url, accepted|
|
|
14
|
+
request_thread = Thread.new do
|
|
15
|
+
Wreq.get(url, timeout: 60)
|
|
16
|
+
rescue Interrupt, StandardError => error
|
|
17
|
+
error
|
|
18
|
+
end
|
|
19
|
+
request_thread.report_on_exception = false
|
|
20
|
+
|
|
21
|
+
Timeout.timeout(5) { accepted.pop }
|
|
22
|
+
request_thread.wakeup
|
|
23
|
+
|
|
24
|
+
assert request_thread.join(5), "Interrupted request thread should stop"
|
|
25
|
+
|
|
26
|
+
error = request_thread.value
|
|
27
|
+
assert_instance_of Wreq::InterruptError, error
|
|
28
|
+
refute_kind_of StandardError, error
|
|
29
|
+
end
|
|
30
|
+
ensure
|
|
31
|
+
request_thread&.kill
|
|
32
|
+
request_thread&.join(1)
|
|
33
|
+
end
|
|
34
|
+
|
|
4
35
|
def test_network_error_handling
|
|
5
36
|
# Try to connect to a non-existent domain
|
|
6
37
|
response = Wreq.get("https://definitely-not-a-real-domain-12345.com")
|
|
@@ -89,4 +120,27 @@ class ErrorHandlingTest < Minitest::Test
|
|
|
89
120
|
end
|
|
90
121
|
end
|
|
91
122
|
end
|
|
123
|
+
|
|
124
|
+
private
|
|
125
|
+
|
|
126
|
+
def with_hanging_server
|
|
127
|
+
server = TCPServer.new("127.0.0.1", 0)
|
|
128
|
+
accepted = Queue.new
|
|
129
|
+
thread = Thread.new do
|
|
130
|
+
socket = server.accept
|
|
131
|
+
accepted << true
|
|
132
|
+
sleep
|
|
133
|
+
rescue IOError, SystemCallError
|
|
134
|
+
nil
|
|
135
|
+
ensure
|
|
136
|
+
socket&.close unless socket&.closed?
|
|
137
|
+
end
|
|
138
|
+
thread.report_on_exception = false
|
|
139
|
+
|
|
140
|
+
yield "http://127.0.0.1:#{server.addr[1]}/", accepted
|
|
141
|
+
ensure
|
|
142
|
+
server&.close unless server&.closed?
|
|
143
|
+
thread&.kill
|
|
144
|
+
thread&.join(1)
|
|
145
|
+
end
|
|
92
146
|
end
|