async icon indicating copy to clipboard operation
async copied to clipboard

panic with message '`ToSendSerializer` can't fail: Other'

Open jgallagher opened this issue 2 years ago • 0 comments

Reproducer:

[dependencies]
erased-serde = "0.3"
serde = "1.0"
slog = { version = "2.7", features = ["nested-values"] }
slog-async = "2.8"
slog-term = "2.9"
use serde::Serialize;
use slog::{info, o, Drain, SerdeValue, Value};

struct MyType;

impl Serialize for MyType {
    fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        todo!()
    }
}

impl Value for MyType {
    fn serialize(
        &self,
        _record: &slog::Record,
        key: slog::Key,
        serializer: &mut dyn slog::Serializer,
    ) -> slog::Result {
        serializer.emit_serde(key, self)
    }
}

impl SerdeValue for MyType {
    fn as_serde(&self) -> &dyn erased_serde::Serialize {
        todo!()
    }

    fn to_sendable(&self) -> Box<dyn SerdeValue + Send + 'static> {
        todo!()
    }
}

fn main() {
    let decorator = slog_term::TermDecorator::new().build();
    let drain = slog_term::CompactFormat::new(decorator).build().fuse();
    let drain = slog_async::Async::new(drain).build().fuse();

    let log = slog::Logger::root(drain, o!());

    info!(log, "boom"; "value" => MyType);
}

I would expect this to panic at one of the three todo!()s, but it panics inside slog-async:

thread 'main' panicked at '`ToSendSerializer` can't fail: Other', /home/john/.cargo/registry/src/index.crates.io-6f17d22bba15001f/slog-async-2.8.0/lib.rs:496:14
stack backtrace:
   0: rust_begin_unwind
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/std/src/panicking.rs:593:5
   1: core::panicking::panic_fmt
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/panicking.rs:67:14
   2: core::result::unwrap_failed
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/result.rs:1651:5
   3: core::result::Result<T,E>::expect
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/result.rs:1033:23
   4: slog_async::AsyncRecord::from
             at /home/john/.cargo/registry/src/index.crates.io-6f17d22bba15001f/slog-async-2.8.0/lib.rs:493:9
   5: <slog_async::AsyncCore as slog::Drain>::log
             at /home/john/.cargo/registry/src/index.crates.io-6f17d22bba15001f/slog-async-2.8.0/lib.rs:475:19
   6: <slog_async::Async as slog::Drain>::log
             at /home/john/.cargo/registry/src/index.crates.io-6f17d22bba15001f/slog-async-2.8.0/lib.rs:788:15
   7: <slog::Fuse<D> as slog::Drain>::log
             at /home/john/.cargo/registry/src/index.crates.io-6f17d22bba15001f/slog-2.7.0/src/lib.rs:1942:17
   8: <alloc::sync::Arc<D> as slog::Drain>::log
             at /home/john/.cargo/registry/src/index.crates.io-6f17d22bba15001f/slog-2.7.0/src/lib.rs:1719:9
   9: slog::Logger<D>::log
             at /home/john/.cargo/registry/src/index.crates.io-6f17d22bba15001f/slog-2.7.0/src/lib.rs:1233:17
  10: slog_async_panic_cantfail::main
             at ./src/main.rs:43:5
  11: core::ops::function::FnOnce::call_once
             at /rustc/5680fa18feaa87f3ff04063800aec256c3d4b4be/library/core/src/ops/function.rs:250:5

If I understand correctly, the root cause is that MyType implements SerdeValue but does not implement serialize_fallback(). The default implementation returns an error, and the logger I've set up (at least with the list of Cargo features specified above) does not support nested values.

However, I don't think slog-async should panic here, and certainly not with a can't fail message - that's quite confusing. :) I'm not entirely sure of the call stack through all the dynamic trait objects (and the backtrace above doesn't seem to help much), but I think the serialize call being unwrapped is failing before it even gets to the infallible emit_* methods on ToSendSerializer?

jgallagher avatar Dec 13 '23 18:12 jgallagher