Skip to content

Commit 5b7643d

Browse files
authored
Use ntex-error::Error (#84)
1 parent c4b705d commit 5b7643d

File tree

16 files changed

+355
-186
lines changed

16 files changed

+355
-186
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changes
22

3+
## [3.8.0] - 2026-03-07
4+
5+
* Use ntex-error::Error
6+
37
## [3.7.1] - 2026-02-16
48

59
* ServiceConfig is not Clone

Cargo.toml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ntex-h2"
3-
version = "3.7.1"
3+
version = "3.8.0"
44
license = "MIT OR Apache-2.0"
55
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
66
description = "An HTTP/2 client and server"
@@ -27,11 +27,12 @@ ntex-bytes = "1.5"
2727
ntex-codec = "1.1"
2828
ntex-dispatcher = "3"
2929
ntex-http = "1"
30-
ntex-io = "3.7"
31-
ntex-net = "3"
32-
ntex-service = "4.4"
30+
ntex-io = "3.9"
31+
ntex-net = "3.8"
32+
ntex-service = "4.6"
3333
ntex-util = "3"
34-
ntex-server = "3.7"
34+
ntex-server = "3.9"
35+
ntex-error = "1.0"
3536

3637
bitflags = "2"
3738
foldhash = "0.2"
@@ -51,8 +52,8 @@ walkdir = "2.3.2"
5152
serde = "1"
5253
serde_json = "1"
5354

54-
ntex = { version = "3.2", features = ["openssl"] }
55-
ntex-tls = { version = "3", features = ["openssl"] }
55+
ntex = { version = "3.6", features = ["openssl"] }
56+
ntex-tls = { version = "3.4", features = ["openssl"] }
5657
openssl = "0.10"
5758

5859
# Examples

examples/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub async fn main() -> Result<(), Box<dyn Error>> {
1717

1818
let pool = client::Client::builder(
1919
"127.0.0.1:5928",
20-
ntex_tls::openssl::SslConnector::new(builder.build()),
20+
ntex_tls::openssl::SslConnector2::new(builder.build()),
2121
)
2222
.scheme(Scheme::HTTPS)
2323
.build(SharedCfg::default())

examples/server.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use ntex::service::{cfg::SharedCfg, fn_service};
2+
use ntex_error::Error;
23
use ntex_h2::{Control, Message, MessageKind, OperationError, ServiceConfig, server};
34
use ntex_http::{HeaderMap, StatusCode, header};
45
use ntex_util::time::{Millis, sleep};
@@ -49,7 +50,7 @@ async fn main() -> std::io::Result<()> {
4950
log::trace!("Disconnect: {:?}", err);
5051
}
5152
}
52-
Ok::<_, OperationError>(())
53+
Ok::<_, Error<OperationError>>(())
5354
}))
5455
.control(|msg: Control<_>| async move {
5556
log::trace!("Control message: {:?}", msg);

examples/tls-server.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use ntex::service::{ServiceFactory, fn_service};
2+
use ntex_error::Error;
23
use ntex_h2::{Control, Message, MessageKind, OperationError, server};
34
use ntex_http::{HeaderMap, StatusCode, header};
45
use ntex_tls::openssl::SslAcceptor;
@@ -71,7 +72,7 @@ async fn main() -> std::io::Result<()> {
7172
log::trace!("Disconnect: {:?}", err);
7273
}
7374
}
74-
Ok::<_, OperationError>(())
75+
Ok::<_, Error<OperationError>>(())
7576
}))
7677
.control(|msg: Control<_>| async move {
7778
println!("Control message: {:?}", msg);

src/client/connector.rs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::marker::PhantomData;
22

33
use ntex_bytes::ByteString;
4+
use ntex_error::Error;
45
use ntex_http::uri::Scheme;
56
use ntex_io::IoBoxed;
6-
use ntex_net::connect::{Address, Connect, ConnectError, Connector as DefaultConnector};
7+
use ntex_net::connect::{Address, Connect, ConnectError, Connector2 as DefaultConnector};
78
use ntex_service::cfg::{Cfg, SharedCfg};
89
use ntex_service::{IntoServiceFactory, Service, ServiceCtx, ServiceFactory};
910
use ntex_util::{channel::pool, time::timeout_checked};
@@ -24,7 +25,7 @@ pub struct Connector<A: Address, T> {
2425
impl<A, T> Connector<A, T>
2526
where
2627
A: Address,
27-
T: ServiceFactory<Connect<A>, SharedCfg, Error = ConnectError>,
28+
T: ServiceFactory<Connect<A>, SharedCfg, Error = Error<ConnectError>>,
2829
IoBoxed: From<T::Response>,
2930
{
3031
/// Create new http2 connector
@@ -66,7 +67,7 @@ where
6667
pub fn connector<U, F>(&self, svc: F) -> Connector<A, U>
6768
where
6869
F: IntoServiceFactory<U, Connect<A>, SharedCfg>,
69-
U: ServiceFactory<Connect<A>, SharedCfg, Error = ConnectError>,
70+
U: ServiceFactory<Connect<A>, SharedCfg, Error = Error<ConnectError>>,
7071
IoBoxed: From<U::Response>,
7172
{
7273
Connector {
@@ -81,11 +82,11 @@ where
8182
impl<A, T> ServiceFactory<A, SharedCfg> for Connector<A, T>
8283
where
8384
A: Address,
84-
T: ServiceFactory<Connect<A>, SharedCfg, Error = ConnectError>,
85+
T: ServiceFactory<Connect<A>, SharedCfg, Error = Error<ConnectError>>,
8586
IoBoxed: From<T::Response>,
8687
{
8788
type Response = SimpleClient;
88-
type Error = ClientError;
89+
type Error = Error<ClientError>;
8990
type InitError = T::InitError;
9091
type Service = ConnectorService<A, T::Service>;
9192

@@ -114,19 +115,24 @@ pub struct ConnectorService<A, T> {
114115
impl<A, T> Service<A> for ConnectorService<A, T>
115116
where
116117
A: Address,
117-
T: Service<Connect<A>, Error = ConnectError>,
118+
T: Service<Connect<A>, Error = Error<ConnectError>>,
118119
IoBoxed: From<T::Response>,
119120
{
120121
type Response = SimpleClient;
121-
type Error = ClientError;
122+
type Error = Error<ClientError>;
122123

123124
/// Connect to http2 server
124-
async fn call(&self, req: A, ctx: ServiceCtx<'_, Self>) -> Result<SimpleClient, ClientError> {
125+
async fn call(&self, req: A, ctx: ServiceCtx<'_, Self>) -> Result<SimpleClient, Self::Error> {
125126
let authority = ByteString::from(req.host());
126127

127128
let fut = async {
128-
Ok::<_, ClientError>(SimpleClient::with_params(
129-
ctx.call(&self.svc, Connect::new(req)).await?.into(),
129+
let io = ctx
130+
.call(&self.svc, Connect::new(req))
131+
.await
132+
.map_err(|e| e.map(ClientError::from))?;
133+
134+
Ok::<_, Error<ClientError>>(SimpleClient::with_params(
135+
io.into(),
130136
self.config.clone(),
131137
&self.scheme,
132138
authority,
@@ -138,11 +144,13 @@ where
138144

139145
timeout_checked(self.config.handshake_timeout, fut)
140146
.await
141-
.map_err(|()| ClientError::HandshakeTimeout)
147+
.map_err(|()| {
148+
Error::from(ClientError::HandshakeTimeout).set_service(self.config.service())
149+
})
142150
.and_then(|item| item)
143151
}
144152

145-
ntex_service::forward_ready!(svc);
146-
ntex_service::forward_poll!(svc);
153+
ntex_service::forward_ready!(svc, |e| e.map(ClientError::from));
154+
ntex_service::forward_poll!(svc, |e| e.map(ClientError::from));
147155
ntex_service::forward_shutdown!(svc);
148156
}

src/client/mod.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
//! Http2 client
2-
use std::rc::Rc;
2+
use std::io;
3+
4+
use ntex_error::{ErrorDiagnostic, ErrorType};
5+
use ntex_net::connect::ConnectError;
6+
use ntex_util::channel::Canceled;
37

48
mod connector;
59
mod pool;
@@ -18,7 +22,7 @@ pub use self::stream::{RecvStream, SendStream};
1822
pub enum ClientError {
1923
/// Protocol error
2024
#[error("Protocol error: {0}")]
21-
Protocol(Rc<ConnectionError>),
25+
Protocol(ConnectionError),
2226
/// Operation error
2327
#[error("Operation error: {0}")]
2428
Operation(#[from] OperationError),
@@ -30,27 +34,21 @@ pub enum ClientError {
3034
HandshakeTimeout,
3135
/// Connect error
3236
#[error("Connect error: {0}")]
33-
Connect(Rc<ntex_net::connect::ConnectError>),
37+
Connect(#[from] ConnectError),
3438
/// Peer disconnected
3539
#[error("Peer disconnected err: {0}")]
36-
Disconnected(#[from] std::io::Error),
40+
Disconnected(#[from] io::Error),
3741
}
3842

3943
impl From<ConnectionError> for ClientError {
4044
fn from(err: ConnectionError) -> Self {
41-
Self::Protocol(Rc::new(err))
42-
}
43-
}
44-
45-
impl From<ntex_util::channel::Canceled> for ClientError {
46-
fn from(err: ntex_util::channel::Canceled) -> Self {
47-
Self::Disconnected(std::io::Error::other(err))
45+
Self::Protocol(err)
4846
}
4947
}
5048

51-
impl From<ntex_net::connect::ConnectError> for ClientError {
52-
fn from(err: ntex_net::connect::ConnectError) -> Self {
53-
Self::Connect(Rc::new(err))
49+
impl From<Canceled> for ClientError {
50+
fn from(err: Canceled) -> Self {
51+
Self::Disconnected(io::Error::other(err))
5452
}
5553
}
5654

@@ -63,12 +61,20 @@ impl Clone for ClientError {
6361
Self::HandshakeTimeout => Self::HandshakeTimeout,
6462
Self::Connect(err) => Self::Connect(err.clone()),
6563
Self::Disconnected(err) => {
66-
Self::Disconnected(std::io::Error::new(err.kind(), format!("{err}")))
64+
Self::Disconnected(io::Error::new(err.kind(), format!("{err}")))
6765
}
6866
}
6967
}
7068
}
7169

70+
impl ErrorDiagnostic for ClientError {
71+
type Kind = ErrorType;
72+
73+
fn kind(&self) -> Self::Kind {
74+
ErrorType::Service
75+
}
76+
}
77+
7278
#[cfg(feature = "unstable")]
7379
pub trait Observer {
7480
/// New request is prepared

src/client/pool.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use std::{cell::Cell, cell::RefCell, fmt, marker::PhantomData, rc::Rc, time::Dur
33

44
use nanorand::{Rng, WyRand};
55
use ntex_bytes::ByteString;
6+
use ntex_error::Error;
67
use ntex_http::{HeaderMap, Method, uri::Scheme};
78
use ntex_io::IoBoxed;
8-
use ntex_net::connect::{Address, Connect, ConnectError, Connector as DefaultConnector};
9+
use ntex_net::connect::{Address, Connect, ConnectError, Connector2 as DefaultConnector};
910
use ntex_service::cfg::{Cfg, SharedCfg};
1011
use ntex_service::{IntoServiceFactory, Pipeline, ServiceFactory};
1112
use ntex_util::time::{Millis, Seconds, timeout_checked};
@@ -15,8 +16,8 @@ use super::stream::{InflightStorage, RecvStream, SendStream};
1516
use super::{ClientError, simple::SimpleClient};
1617
use crate::ServiceConfig;
1718

18-
type Fut = BoxFuture<'static, Result<IoBoxed, ConnectError>>;
19-
type Connector = Box<dyn Fn() -> BoxFuture<'static, Result<IoBoxed, ConnectError>>>;
19+
type Fut = BoxFuture<'static, Result<IoBoxed, Error<ConnectError>>>;
20+
type Connector = Box<dyn Fn() -> BoxFuture<'static, Result<IoBoxed, Error<ConnectError>>>>;
2021

2122
#[derive(Clone)]
2223
/// Manages http client network connectivity.
@@ -48,7 +49,7 @@ impl Client {
4849
where
4950
A: Address + Clone,
5051
F: IntoServiceFactory<T, Connect<A>, SharedCfg>,
51-
T: ServiceFactory<Connect<A>, SharedCfg, Error = ConnectError> + 'static,
52+
T: ServiceFactory<Connect<A>, SharedCfg, Error = Error<ConnectError>> + 'static,
5253
IoBoxed: From<T::Response>,
5354
Connect<A>: From<U>,
5455
{
@@ -62,16 +63,16 @@ impl Client {
6263
path: ByteString,
6364
headers: HeaderMap,
6465
eof: bool,
65-
) -> Result<(SendStream, RecvStream), ClientError> {
66+
) -> Result<(SendStream, RecvStream), Error<ClientError>> {
6667
self.client()
6768
.await?
6869
.send(method, path, headers, eof)
6970
.await
70-
.map_err(From::from)
71+
.map_err(|e| e.map(ClientError::from))
7172
}
7273

7374
/// Get client from the pool
74-
pub async fn client(&self) -> Result<SimpleClient, ClientError> {
75+
pub async fn client(&self) -> Result<SimpleClient, Error<ClientError>> {
7576
loop {
7677
let (client, num) = self.get_client();
7778

@@ -82,7 +83,7 @@ impl Client {
8283
}
8384
}
8485

85-
async fn connect(&self, num: usize) -> Result<(), ClientError> {
86+
async fn connect(&self, num: usize) -> Result<(), Error<ClientError>> {
8687
let cfg = &self.inner.config;
8788

8889
// can create new connection
@@ -102,7 +103,8 @@ impl Client {
102103
// wait for available connection
103104
let (tx, rx) = cfg.pool.channel();
104105
self.waiters.borrow_mut().push_back(tx);
105-
rx.await?;
106+
rx.await
107+
.map_err(|e| Error::new(e, self.inner.cfg.service()))?;
106108
}
107109
Ok(())
108110
}
@@ -157,7 +159,7 @@ impl Client {
157159
}
158160
}
159161

160-
async fn create_connection(&self) -> Result<(), ClientError> {
162+
async fn create_connection(&self) -> Result<(), Error<ClientError>> {
161163
let (tx, rx) = oneshot::channel();
162164

163165
let inner = self.inner.clone();
@@ -188,8 +190,8 @@ impl Client {
188190
.set(inner.config.total_connections.get() + 1);
189191
Ok(())
190192
}
191-
Ok(Err(err)) => Err(ClientError::from(err)),
192-
Err(()) => Err(ClientError::HandshakeTimeout),
193+
Ok(Err(err)) => Err(err.map(ClientError::from)),
194+
Err(()) => Err(Error::from(ClientError::HandshakeTimeout)),
193195
};
194196
inner.config.connecting.set(false);
195197
for waiter in waiters.borrow_mut().drain(..) {
@@ -205,7 +207,8 @@ impl Client {
205207
let _ = tx.send(res);
206208
});
207209

208-
rx.await?
210+
rx.await
211+
.map_err(|e| Error::new(e, self.inner.cfg.service()))?
209212
}
210213

211214
#[inline]
@@ -298,7 +301,7 @@ struct InnerConfig {
298301
impl<A, T> ClientBuilder<A, T>
299302
where
300303
A: Address + Clone,
301-
T: ServiceFactory<Connect<A>, SharedCfg, Error = ConnectError>,
304+
T: ServiceFactory<Connect<A>, SharedCfg, Error = Error<ConnectError>>,
302305
IoBoxed: From<T::Response>,
303306
{
304307
fn new<U, F>(addr: U, connector: F) -> Self
@@ -412,7 +415,7 @@ where
412415
pub fn connector<U, F>(self, connector: F) -> ClientBuilder<A, U>
413416
where
414417
F: IntoServiceFactory<U, Connect<A>, SharedCfg>,
415-
U: ServiceFactory<Connect<A>, SharedCfg, Error = ConnectError> + 'static,
418+
U: ServiceFactory<Connect<A>, SharedCfg, Error = Error<ConnectError>> + 'static,
416419
IoBoxed: From<U::Response>,
417420
{
418421
ClientBuilder {
@@ -427,7 +430,7 @@ where
427430
impl<A, T> ClientBuilder<A, T>
428431
where
429432
A: Address + Clone,
430-
T: ServiceFactory<Connect<A>, SharedCfg, Error = ConnectError> + 'static,
433+
T: ServiceFactory<Connect<A>, SharedCfg, Error = Error<ConnectError>> + 'static,
431434
IoBoxed: From<T::Response>,
432435
{
433436
/// Finish configuration process and create connections pool.

0 commit comments

Comments
 (0)