#nightly #macro #log-error #termination #proc-macro #wraps #fn

macro log-termination

A proc macro which wraps fn main() in a Termination newtype and sends the error to log::error!

1 unstable release

0.1.0 Dec 17, 2019

#11 in #termination

AGPL-3.0

16KB
166 lines

log-termination

Provides an attribute proc macro for your fn main() -> Result<(), Box<dyn Error>> which sends returned errors to log::error!.

#![feature(try_trait)]
#![feature(termination_trait_lib)]

use log_termination::log_termination;

#[log_termination]
fn main() -> Result<(), Box<dyn std::error::Error>> {
  // set up logging, e.g. fern

  std::fs::metadata("non-existing-file")?;
  // will call log::error!("No such file or directory (os error 2)") before exiting
}

lib.rs:

This attribute proc macro should be applied to main functions of the form main() -> Result<(), Box<dyn Error>>; it wraps the returned value in a newtype which implements Termination and displays the returned error via error!. This macro exists purely for convenience.

Your create needs the try_trait and termination_trait_lib features.

For example:

#![feature(try_trait)]
#![feature(termination_trait_lib)]

use std::error::Error;
use std::io::ErrorKind;

#[macro_use]
extern crate log;
extern crate fern;

extern crate log_termination;
use log_termination::log_termination;

#[log_termination]
fn main() -> Result<(), Box<dyn Error>> {
  fern::Dispatch::new()
    .format(|o, m, r| { o.finish(format_args!(
      "[{}:{}] {} {}: {}",
      r.file().unwrap(),
      r.line().unwrap(),
      chrono::Local::now().format("%F %T"),
      r.level(),
      m
    ))})
    .level(log::LevelFilter::Error)
    .chain(std::io::stderr())
    .apply()?;

  return Err(Box::new(std::io::Error::new(ErrorKind::Other, "SNAFU")));

  // This code is valid, but unreachable:
  //Ok(())
}

Dependencies

~4–5MB
~99K SLoC