Introduce smaller error type

This commit is contained in:
Dominik Werder
2023-06-13 11:14:21 +02:00
parent 3b7b024200
commit 5d8a00db2d
14 changed files with 1591 additions and 1419 deletions
+2 -2
View File
@@ -1355,7 +1355,7 @@ impl CaConn {
},
Err(e) => {
error!("got error item from CaProto {e:?}");
Ready(Some(Err(e)))
Ready(Some(Err(e.to_string().into())))
}
},
Ready(None) => {
@@ -1586,7 +1586,7 @@ impl CaConn {
// TODO remove the need for this:
cx.waker().wake_by_ref();
}
res
res.map_err(|e| Error::from(e.to_string()))
}
// `?` works not in here.
+4 -4
View File
@@ -270,7 +270,7 @@ impl FindIocStream {
panic!();
}
let mut nb = crate::netbuf::NetBuf::new(2048);
nb.put_slice(&buf[..ec as usize])?;
nb.put_slice(&buf[..ec as usize]).map_err(|e| e.to_string())?;
let mut msgs = Vec::new();
let mut accounted = 0;
loop {
@@ -282,7 +282,7 @@ impl FindIocStream {
error!("incomplete message, not enough for header");
break;
}
let hi = HeadInfo::from_netbuf(&mut nb)?;
let hi = HeadInfo::from_netbuf(&mut nb).map_err(|e| e.to_string())?;
if hi.cmdid() == 0 && hi.payload() == 0 {
} else if hi.cmdid() == 6 && hi.payload() == 8 {
} else {
@@ -292,8 +292,8 @@ impl FindIocStream {
error!("incomplete message, missing payload");
break;
}
let msg = CaMsg::from_proto_infos(&hi, nb.data(), 32)?;
nb.adv(hi.payload())?;
let msg = CaMsg::from_proto_infos(&hi, nb.data(), 32).map_err(|e| e.to_string())?;
nb.adv(hi.payload()).map_err(|e| e.to_string())?;
msgs.push(msg);
accounted += 16 + hi.payload();
}
+87 -73
View File
@@ -1,16 +1,59 @@
use crate::netbuf;
use crate::netbuf::NetBuf;
use err::Error;
use futures_util::{pin_mut, Stream};
use futures_util::pin_mut;
use futures_util::Stream;
use log::*;
use netpod::timeunits::*;
use std::collections::{BTreeMap, VecDeque};
use std::collections::BTreeMap;
use std::collections::VecDeque;
use std::io;
use std::net::SocketAddrV4;
use std::num::{NonZeroU16, NonZeroU64};
use std::num::NonZeroU16;
use std::num::NonZeroU64;
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
use std::task::Context;
use std::task::Poll;
use tokio::io::AsyncRead;
use tokio::io::AsyncWrite;
use tokio::io::ReadBuf;
use tokio::net::TcpStream;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("{0}")]
NetBuf(#[from] netbuf::Error),
#[error("BufferTooSmallForNeedMin({0}, {1})")]
BufferTooSmallForNeedMin(usize, usize),
#[error("IO({0})")]
IO(#[from] io::Error),
#[error("BadSlice")]
BadSlice,
#[error("BadCaDbrTypeId({0})")]
BadCaDbrTypeId(u16),
#[error("BadCaScalarTypeId({0})")]
BadCaScalarTypeId(u16),
#[error("GetValHelpInnerTypeMismatch")]
GetValHelpInnerTypeMismatch,
#[error("GetValHelpTodoWaveform")]
GetValHelpTodoWaveform,
#[error("NotEnoughPayload")]
NotEnoughPayload,
#[error("TodoConversionArray")]
TodoConversionArray,
#[error("CaProtoVersionMissing")]
CaProtoVersionMissing,
#[error("NotEnoughPayloadTimeMetadata({0})")]
NotEnoughPayloadTimeMetadata(usize),
#[error("MismatchDbrTimeType")]
MismatchDbrTimeType,
#[error("BadCaCount")]
BadCaCount,
#[error("CaCommandNotSupported({0})")]
CaCommandNotSupported(u16),
#[error("ParseAttemptInDoneState")]
ParseAttemptInDoneState,
}
const CA_PROTO_VERSION: u16 = 13;
const EPICS_EPOCH_OFFSET: u64 = 631152000;
@@ -126,10 +169,7 @@ pub struct CaDbrType {
impl CaDbrType {
pub fn from_ca_u16(k: u16) -> Result<Self, Error> {
if k > 20 {
return Err(Error::with_msg_no_trace(format!(
"can not understand ca dbr type id {}",
k
)));
return Err(Error::BadCaDbrTypeId(k));
}
let (meta, k) = if k >= 14 {
(CaDbrMetaType::Time, k - 14)
@@ -147,7 +187,7 @@ impl CaDbrType {
6 => F64,
3 => Enum,
0 => String,
k => return Err(Error::with_msg_no_trace(format!("bad ca scalar type id: {k}"))),
k => return Err(Error::BadCaScalarTypeId(k)),
};
Ok(CaDbrType { meta, scalar_type })
}
@@ -178,13 +218,11 @@ impl GetValHelp<i8> for CaDataValue {
CaDataValue::Scalar(v) => match v {
CaDataScalarValue::I8(v) => Ok(v),
_ => {
let ty = std::any::type_name::<Self::ScalTy>();
Err(Error::with_msg_no_trace(format!(
"GetValHelp inner type mismatch {ty} vs {v:?}",
)))
//let ty = any::type_name::<Self::ScalTy>();
Err(Error::GetValHelpInnerTypeMismatch)
}
},
_ => Err(Error::with_msg_no_trace("GetValHelp waveform not supported")),
_ => Err(Error::GetValHelpTodoWaveform),
}
}
}
@@ -196,13 +234,11 @@ impl GetValHelp<i16> for CaDataValue {
CaDataValue::Scalar(v) => match v {
CaDataScalarValue::I16(v) => Ok(v),
_ => {
let ty = std::any::type_name::<Self::ScalTy>();
Err(Error::with_msg_no_trace(format!(
"GetValHelp inner type mismatch {ty} vs {v:?}",
)))
//let ty = any::type_name::<Self::ScalTy>();
Err(Error::GetValHelpInnerTypeMismatch)
}
},
_ => Err(Error::with_msg_no_trace("GetValHelp waveform not supported")),
_ => Err(Error::GetValHelpTodoWaveform),
}
}
}
@@ -214,13 +250,11 @@ impl GetValHelp<i32> for CaDataValue {
CaDataValue::Scalar(v) => match v {
CaDataScalarValue::I32(v) => Ok(v),
_ => {
let ty = std::any::type_name::<Self::ScalTy>();
Err(Error::with_msg_no_trace(format!(
"GetValHelp inner type mismatch {ty} vs {v:?}",
)))
//let ty = any::type_name::<Self::ScalTy>();
Err(Error::GetValHelpInnerTypeMismatch)
}
},
_ => Err(Error::with_msg_no_trace("GetValHelp waveform not supported")),
_ => Err(Error::GetValHelpTodoWaveform),
}
}
}
@@ -232,13 +266,11 @@ impl GetValHelp<f32> for CaDataValue {
CaDataValue::Scalar(v) => match v {
CaDataScalarValue::F32(v) => Ok(v),
_ => {
let ty = std::any::type_name::<Self::ScalTy>();
Err(Error::with_msg_no_trace(format!(
"GetValHelp inner type mismatch {ty} vs {v:?}",
)))
//let ty = any::type_name::<Self::ScalTy>();
Err(Error::GetValHelpInnerTypeMismatch)
}
},
_ => Err(Error::with_msg_no_trace("GetValHelp waveform not supported")),
_ => Err(Error::GetValHelpTodoWaveform),
}
}
}
@@ -250,13 +282,11 @@ impl GetValHelp<f64> for CaDataValue {
CaDataValue::Scalar(v) => match v {
CaDataScalarValue::F64(v) => Ok(v),
_ => {
let ty = std::any::type_name::<Self::ScalTy>();
Err(Error::with_msg_no_trace(format!(
"GetValHelp inner type mismatch {ty} vs {v:?}",
)))
//let ty = any::type_name::<Self::ScalTy>();
Err(Error::GetValHelpInnerTypeMismatch)
}
},
_ => Err(Error::with_msg_no_trace("GetValHelp waveform not supported")),
_ => Err(Error::GetValHelpTodoWaveform),
}
}
}
@@ -529,13 +559,9 @@ macro_rules! convert_scalar_value {
type ST = $st;
const STL: usize = std::mem::size_of::<ST>();
if $buf.len() < STL {
return Err(Error::with_msg_no_trace(format!(
"not enough payload for {} {}",
std::any::type_name::<ST>(),
$buf.len()
)));
return Err(Error::NotEnoughPayload);
}
let v = ST::from_be_bytes($buf[..STL].try_into()?);
let v = ST::from_be_bytes($buf[..STL].try_into().map_err(|_| Error::BadSlice)?);
CaDataValue::Scalar(CaDataScalarValue::$var(v))
}};
}
@@ -549,7 +575,7 @@ macro_rules! convert_wave_value {
// TODO should optimize?
let mut bb = &$buf[..];
for _ in 0..nn {
let v = ST::from_be_bytes(bb[..STL].try_into()?);
let v = ST::from_be_bytes(bb[..STL].try_into().map_err(|_| Error::BadSlice)?);
bb = &bb[STL..];
a.push(v);
}
@@ -634,9 +660,7 @@ impl CaMsg {
CaScalarType::String => CaDataValue::Scalar(CaDataScalarValue::String("todo-array-string".into())),
_ => {
warn!("TODO conversion array {scalar_type:?}");
return Err(Error::with_msg_no_trace(format!(
"can not yet handle conversion of type array {scalar_type:?}"
)));
return Err(Error::TodoConversionArray);
}
};
Ok(val)
@@ -681,9 +705,9 @@ impl CaMsg {
warn!("protocol error: search result is expected with data count 0");
}
if payload.len() < 2 {
return Err(Error::with_msg_no_trace("server did not include protocol version"));
return Err(Error::CaProtoVersionMissing);
}
let proto_version = u16::from_be_bytes(payload[0..2].try_into()?);
let proto_version = u16::from_be_bytes(payload[0..2].try_into().map_err(|_| Error::BadSlice)?);
CaMsg {
ty: CaMsgTy::SearchRes(SearchRes {
tcp_port: hi.data_type,
@@ -724,22 +748,16 @@ impl CaMsg {
let ca_dbr_ty = CaDbrType::from_ca_u16(hi.data_type)?;
if let CaDbrMetaType::Time = ca_dbr_ty.meta {
} else {
return Err(Error::with_msg_no_trace(format!(
"expect ca dbr time type, got: {:?}",
ca_dbr_ty
)));
return Err(Error::MismatchDbrTimeType);
}
if payload.len() < 12 {
return Err(Error::with_msg_no_trace(format!(
"not enough payload for time metadata {}",
payload.len()
)));
return Err(Error::NotEnoughPayloadTimeMetadata(payload.len()));
}
let ca_status = u16::from_be_bytes(payload[0..2].try_into()?);
let ca_severity = u16::from_be_bytes(payload[2..4].try_into()?);
let ca_secs = u32::from_be_bytes(payload[4..8].try_into()?);
let ca_nanos = u32::from_be_bytes(payload[8..12].try_into()?);
let ca_sh = Shape::from_ca_count(hi.data_count)?;
let ca_status = u16::from_be_bytes(payload[0..2].try_into().map_err(|_| Error::BadSlice)?);
let ca_severity = u16::from_be_bytes(payload[2..4].try_into().map_err(|_| Error::BadSlice)?);
let ca_secs = u32::from_be_bytes(payload[4..8].try_into().map_err(|_| Error::BadSlice)?);
let ca_nanos = u32::from_be_bytes(payload[8..12].try_into().map_err(|_| Error::BadSlice)?);
let ca_sh = Shape::from_ca_count(hi.data_count).map_err(|_| Error::BadCaCount)?;
let meta_padding = match ca_dbr_ty.meta {
CaDbrMetaType::Plain => 0,
CaDbrMetaType::Status => match ca_dbr_ty.scalar_type {
@@ -792,11 +810,11 @@ impl CaMsg {
}
15 => {
if payload.len() == 8 {
let v = u64::from_be_bytes(payload.try_into()?);
let v = u64::from_be_bytes(payload.try_into().map_err(|_| Error::BadSlice)?);
info!("Payload as u64: {v}");
let v = i64::from_be_bytes(payload.try_into()?);
let v = i64::from_be_bytes(payload.try_into().map_err(|_| Error::BadSlice)?);
info!("Payload as i64: {v}");
let v = f64::from_be_bytes(payload.try_into()?);
let v = f64::from_be_bytes(payload.try_into().map_err(|_| Error::BadSlice)?);
info!("Payload as f64: {v}");
} else {
info!(
@@ -816,7 +834,7 @@ impl CaMsg {
}
}
0x17 => CaMsg { ty: CaMsgTy::Echo },
x => return Err(Error::with_msg_no_trace(format!("unsupported ca command {}", x))),
x => return Err(Error::CaCommandNotSupported(x)),
};
Ok(msg)
}
@@ -951,7 +969,7 @@ impl CaProto {
Ok(()) => Ready(Ok(())),
Err(e) => {
error!("advance error {:?}", e);
Ready(Err(e))
Ready(Err(e.into()))
}
},
Err(e) => {
@@ -1004,11 +1022,7 @@ impl CaProto {
let read_res = {
if self.buf.cap() < need_min {
self.state = CaState::Done;
let e = Error::with_msg_no_trace(format!(
"buffer too small for need_min {} {}",
self.buf.cap(),
self.state.need_min()
));
let e = Error::BufferTooSmallForNeedMin(self.buf.cap(), self.state.need_min());
Err(e)
} else if self.buf.len() < need_min {
let (w, mut rbuf) = self.inpbuf_conn(need_min);
@@ -1037,7 +1051,7 @@ impl CaProto {
Ok(()) => Ok(Some(Ready(CaItem::empty()))),
Err(e) => {
error!("netbuf wadv fail nf {nf}");
Err(e)
Err(e.into())
}
}
}
@@ -1130,7 +1144,7 @@ impl CaProto {
self.state = CaState::StdHead;
Ok(Some(CaItem::Msg(msg)))
}
CaState::Done => Err(Error::with_msg_no_trace("attempt to parse in Done state")),
CaState::Done => Err(Error::ParseAttemptInDoneState),
};
}
}