@@ -27,6 +27,8 @@ use std::str;
2727
2828use crate :: ffi;
2929
30+ pub use crate :: ffi:: ErrLib ;
31+
3032/// Collection of [`Error`]s from OpenSSL.
3133///
3234/// [`Error`]: struct.Error.html
@@ -194,9 +196,20 @@ impl Error {
194196 }
195197 }
196198
199+ /// Get `{lib}_R_{reason}` reason code for the given library, or `None` if the error is from a different library.
200+ ///
201+ /// Libraries are identified by [`ERR_LIB_{name}`(ffi::ERR_LIB_SSL) constants.
202+ #[ inline]
203+ #[ must_use]
204+ #[ track_caller]
205+ pub fn library_reason ( & self , library_code : ErrLib ) -> Option < c_int > {
206+ debug_assert ! ( library_code. 0 < ffi:: ERR_NUM_LIBS . 0 ) ;
207+ ( self . library_code ( ) == library_code. 0 as c_int ) . then_some ( self . reason_code ( ) )
208+ }
209+
197210 /// Returns a raw OpenSSL **packed** error code for this error, which **can't be reliably compared to any error constant**.
198211 ///
199- /// Use [`Error::library_code()`] and [`Error::reason_code ()`] instead.
212+ /// Use [`Error::library_code()`] and [`Error::library_reason ()`] instead.
200213 /// Packed error codes are different than [SSL error codes](crate::ssl::ErrorCode).
201214 #[ must_use]
202215 pub fn code ( & self ) -> c_uint {
@@ -223,7 +236,7 @@ impl Error {
223236
224237 /// Returns the raw OpenSSL error constant for the library reporting the error (`ERR_LIB_{name}`).
225238 ///
226- /// Error [reason codes](Error::reason_code ) are not globally unique, but scoped to each library.
239+ /// Error [reason codes](Error::library_reason ) are not globally unique, but scoped to each library.
227240 #[ must_use]
228241 pub fn library_code ( & self ) -> c_int {
229242 ffi:: ERR_GET_LIB ( self . code )
@@ -249,6 +262,7 @@ impl Error {
249262 /// Returns [library-specific](Error::library_code) reason code corresponding to some of the `{lib}_R_{reason}` constants.
250263 ///
251264 /// Reason codes are ambiguous, and different libraries reuse the same numeric values for different errors.
265+ /// Use [`Error::library_reason`] to compare error codes.
252266 ///
253267 /// For `ERR_LIB_SYS` the reason code is `errno`. `ERR_LIB_USER` can use any values.
254268 /// Other libraries may use [`ERR_R_*`](ffi::ERR_R_FATAL) or their own codes.
0 commit comments