message: Add handling of async errors
diff: @@ -207,6 +207,7 @@ pub(crate) enum ServerOp {
  Info(Box<ServerInfo>),
  Ping,
  Pong,
  + Error(ServerError),
  Message {
  sid: u64,
  subject: String,
  @@ -295,6 +296,17 @@ impl Connection {
  return Ok(Some(ServerOp::Pong));
  }
  + if self.buffer.starts_with(b"-ERR") {
  + if let Some(len) = self.buffer.find(b"\r\n") {
  + let line = std::str::from_utf8(&self.buffer[5..len])
  + .map_err(|err| io::Error::new(io::ErrorKind::InvalidInput, err))?;
  + let error_message = line.trim_matches('\'').to_string();
  + self.buffer.advance(len + 2);
  +
  + return Ok(Some(ServerOp::Error(ServerError::new(error_message))));
  + }
  + }
  +
  if self.buffer.starts_with(b"INFO ") {
  if let Some(len) = self.buffer.find(b"\r\n") {
  let line = std::str::from_utf8(&self.buffer[5..len])
  @@ -1197,6 +1209,30 @@ impl Stream for Subscriber {
  }
  }
  +#[derive(Clone, Debug)]
  +pub enum ServerError {
  + AuthorizationViolation,
  + Other(String),
  +}
  +
  +impl ServerError {
  + fn new(error: String) -> ServerError {
  + match error.as_str() {
  + "authorization violation" => ServerError::AuthorizationViolation,
  + other => ServerError::Other(other.to_string()),
  + }
  + }
  +}
  +
  +impl std::fmt::Display for ServerError {
  + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  + match self {
  + Self::AuthorizationViolation => write!(f, "nats: authorization violation"),
  + Self::Other(error) => write!(f, "nats: {}", error),
  + }
  + }
  +}
  +
  /// Info to construct a CONNECT message.
  #[derive(Clone, Debug, Serialize)]
  #[doc(hidden)]
  