chore(rust): log more errors as tracing::Values (#7208)

Logging these as structured values gives us a better stacktrace in
Sentry (assuming the errors themselves make proper use of defining an
error-chain).
This commit is contained in:
Thomas Eizinger
2024-11-06 01:36:47 +11:00
committed by GitHub
parent 250a31b872
commit 78ebad13ab
22 changed files with 134 additions and 57 deletions

View File

@@ -374,6 +374,7 @@ impl Drop for Callback {
mod async_dns {
use anyhow::{Context as _, Result};
use firezone_logging::anyhow_dyn_err;
use futures::FutureExt as _;
use std::{ffi::c_void, ops::Deref, path::Path, pin::pin};
use tokio::{
@@ -445,11 +446,17 @@ mod async_dns {
}
}
if let Err(error) = listener_4.close() {
tracing::error!(?error, "Error while closing IPv4 DNS listener");
if let Err(e) = listener_4.close() {
tracing::error!(
error = anyhow_dyn_err(&e),
"Error while closing IPv4 DNS listener"
);
}
if let Err(error) = listener_6.close() {
tracing::error!(?error, "Error while closing IPv6 DNS listener");
if let Err(e) = listener_6.close() {
tracing::error!(
error = anyhow_dyn_err(&e),
"Error while closing IPv6 DNS listener"
);
}
Ok(())

View File

@@ -204,7 +204,7 @@ impl Drop for Tun {
);
self.packet_rx.close(); // This avoids a deadlock when we join the worker thread, see PR 5571
if let Err(error) = self.session.shutdown() {
tracing::error!(?error, "wintun::Session::shutdown");
tracing::error!(error = std_dyn_err(&error), "wintun::Session::shutdown");
}
if let Err(error) = self
.recv_thread
@@ -231,7 +231,7 @@ impl Tun {
let adapter = match Adapter::create(&wintun, TUNNEL_NAME, TUNNEL_NAME, Some(uuid)) {
Ok(x) => x,
Err(error) => {
tracing::error!(?error, "Failed in `Adapter::create`");
tracing::error!(error = std_dyn_err(&error), "Failed in `Adapter::create`");
return Err(error)?;
}
};
@@ -385,7 +385,7 @@ fn try_set_mtu(luid: NET_LUID_LH, family: ADDRESS_FAMILY, mtu: u32) -> Result<()
if family == AF_INET6 && error.code() == windows_core::HRESULT::from_win32(0x80070490) {
tracing::debug!(?family, "Couldn't set MTU, maybe IPv6 is disabled.");
} else {
tracing::warn!(?family, ?error, "Couldn't set MTU");
tracing::warn!(?family, error = std_dyn_err(&error), "Couldn't set MTU");
}
return Ok(());
}

View File

@@ -7,6 +7,7 @@ use crate::tun::Tun;
use backoff::ExponentialBackoffBuilder;
use connlib_client_shared::{Callbacks, DisconnectError, Session, V4RouteList, V6RouteList};
use connlib_model::{ResourceId, ResourceView};
use firezone_logging::std_dyn_err;
use firezone_telemetry::{Telemetry, ANDROID_DSN};
use ip_network::{Ipv4Network, Ipv6Network};
use jni::{
@@ -270,7 +271,7 @@ impl Callbacks for CallbackHandler {
fn throw(env: &mut JNIEnv, class: &str, msg: impl Into<JNIString>) {
if let Err(err) = env.throw_new(class, msg) {
// We can't panic, since unwinding across the FFI boundary is UB...
tracing::error!(?err, "failed to throw Java exception");
tracing::error!(error = std_dyn_err(&err), "failed to throw Java exception");
}
}

View File

@@ -2,6 +2,7 @@
use anyhow::Result;
use firezone_headless_client::known_dirs;
use firezone_logging::std_dyn_err;
use rand::{thread_rng, RngCore};
use secrecy::{ExposeSecret, SecretString};
use serde::{Deserialize, Serialize};
@@ -103,7 +104,7 @@ impl Auth {
match this.get_token_from_disk() {
Err(error) => tracing::error!(
?error,
error = std_dyn_err(&error),
"Failed to load token from disk. Will start in signed-out state"
),
Ok(Some(SessionAndToken { session, token: _ })) => {
@@ -129,7 +130,10 @@ impl Auth {
/// Performs I/O.
pub fn sign_out(&mut self) -> Result<(), Error> {
if let Err(error) = self.token_store.delete_credential() {
tracing::warn!(?error, "Couldn't delete token while signing out");
tracing::warn!(
error = std_dyn_err(&error),
"Couldn't delete token while signing out"
);
}
delete_if_exists(&actor_name_path()?)?;
delete_if_exists(&session_data_path()?)?;

View File

@@ -13,6 +13,7 @@ use firezone_headless_client::{
IpcClientMsg::{self, SetDisabledResources},
IpcServerMsg, IpcServiceError, LogFilterReloader,
};
use firezone_logging::{anyhow_dyn_err, std_dyn_err};
use firezone_telemetry::Telemetry;
use secrecy::{ExposeSecret as _, SecretString};
use std::{collections::BTreeSet, ops::ControlFlow, path::PathBuf, time::Instant};
@@ -300,14 +301,14 @@ impl<I: GuiIntegration> Controller<I> {
tracing::debug!("Closing...");
if let Err(error) = dns_notifier.close() {
tracing::error!(?error, "dns_notifier");
tracing::error!(error = anyhow_dyn_err(&error), "dns_notifier");
}
if let Err(error) = network_notifier.close() {
tracing::error!(?error, "network_notifier");
tracing::error!(error = anyhow_dyn_err(&error), "network_notifier");
}
if let Err(error) = self.ipc_client.disconnect_from_ipc().await {
tracing::error!(?error, "ipc_client");
tracing::error!(error = anyhow_dyn_err(&error), "ipc_client");
}
// Don't close telemetry here, `run` will close it.
@@ -379,7 +380,7 @@ impl<I: GuiIntegration> Controller<I> {
tracing::error!("Can't clear logs, we're already waiting on another log-clearing operation");
}
if let Err(error) = logging::clear_gui_logs().await {
tracing::error!(?error, "Failed to clear GUI logs");
tracing::error!(error = anyhow_dyn_err(&error), "Failed to clear GUI logs");
}
self.ipc_client.send_msg(&IpcClientMsg::ClearLogs).await?;
self.clear_logs_callback = Some(completion_tx);
@@ -395,7 +396,7 @@ impl<I: GuiIntegration> Controller<I> {
}
Req::SchemeRequest(url) => {
if let Err(error) = self.handle_deep_link(&url).await {
tracing::error!(?error, "`handle_deep_link` failed");
tracing::error!(error = std_dyn_err(&error), "`handle_deep_link` failed");
}
}
Req::SignIn | Req::SystemTrayMenu(TrayMenuEvent::SignIn) => {
@@ -490,7 +491,7 @@ impl<I: GuiIntegration> Controller<I> {
Ok(flow) => Ok(flow),
// Handles <https://github.com/firezone/firezone/issues/6547> more gracefully so we can still export logs even if we crashed right after sign-in
Err(Error::ConnectToFirezoneFailed(error)) => {
tracing::error!(?error, "Failed to connect to Firezone");
tracing::error!(error = std_dyn_err(&error), "Failed to connect to Firezone");
self.sign_out().await?;
Ok(ControlFlow::Continue(()))
}
@@ -498,7 +499,7 @@ impl<I: GuiIntegration> Controller<I> {
},
ipc::Event::ReadFailed(error) => {
// IPC errors are always fatal
tracing::error!(?error, "IPC read failure");
tracing::error!(error = anyhow_dyn_err(&error), "IPC read failure");
Err(Error::IpcRead)?
}
ipc::Event::Closed => Err(Error::IpcClosed)?,
@@ -554,7 +555,7 @@ impl<I: GuiIntegration> Controller<I> {
tracing::debug!(len = resources.len(), "Got new Resources");
self.status = Status::TunnelReady { resources };
if let Err(error) = self.refresh_system_tray_menu() {
tracing::error!(?error, "Failed to refresh menu");
tracing::error!(error = anyhow_dyn_err(&error), "Failed to refresh menu");
}
self.update_disabled_resources().await?;
@@ -583,7 +584,7 @@ impl<I: GuiIntegration> Controller<I> {
)?;
}
if let Err(error) = self.refresh_system_tray_menu() {
tracing::error!(?error, "Failed to refresh menu");
tracing::error!(error = anyhow_dyn_err(&error), "Failed to refresh menu");
}
}
}
@@ -617,7 +618,7 @@ impl<I: GuiIntegration> Controller<I> {
ran_before::set().await?;
self.status = Status::WaitingForTunnel { start_instant };
if let Err(error) = self.refresh_system_tray_menu() {
tracing::error!(?error, "Failed to refresh menu");
tracing::error!(error = anyhow_dyn_err(&error), "Failed to refresh menu");
}
Ok(())
}
@@ -625,12 +626,12 @@ impl<I: GuiIntegration> Controller<I> {
// This is typically something like, we don't have Internet access so we can't
// open the PhoenixChannel's WebSocket.
tracing::warn!(
?error,
error,
"Failed to connect to Firezone Portal, will try again when the network changes"
);
self.status = Status::RetryingConnection { token };
if let Err(error) = self.refresh_system_tray_menu() {
tracing::error!(?error, "Failed to refresh menu");
tracing::error!(error = anyhow_dyn_err(&error), "Failed to refresh menu");
}
Ok(())
}

View File

@@ -55,7 +55,7 @@ pub fn show_error_dialog(error: &Error) -> Result<()> {
Error::IpcServiceTerminating => "The Firezone IPC service is terminating. Please restart the GUI Client.".to_string(),
Error::Logging(_) => "Logging error".to_string(),
Error::PortalConnection(error) => {
tracing::error!(?error, "Couldn't connect to the Portal");
tracing::error!(%error, "Couldn't connect to the Portal");
"Couldn't connect to the Firezone Portal. Are you connected to the Internet?".to_string()
}
Error::UserNotInFirezoneGroup => format!("You are not a member of the group `{FIREZONE_GROUP}`. Try `sudo usermod -aG {FIREZONE_GROUP} $USER` and then reboot"),

View File

@@ -2,6 +2,7 @@
use anyhow::{bail, Context as _, Result};
use firezone_headless_client::{known_dirs, LogFilterReloader};
use firezone_logging::std_dyn_err;
use serde::Serialize;
use std::{
fs,
@@ -62,7 +63,7 @@ pub fn setup(directives: &str) -> Result<Handles> {
set_global_default(subscriber)?;
if let Err(error) = output_vt100::try_init() {
tracing::debug!(
?error,
error = std_dyn_err(&error),
"Failed to init vt100 terminal colors (expected in release builds and in CI)"
);
}

View File

@@ -5,6 +5,7 @@ use anyhow::{Context as _, Result};
use atomicwrites::{AtomicFile, OverwriteBehavior};
use connlib_model::ResourceId;
use firezone_headless_client::known_dirs;
use firezone_logging::std_dyn_err;
use serde::{Deserialize, Serialize};
use std::{collections::HashSet, io::Write, path::PathBuf};
use url::Url;
@@ -73,7 +74,7 @@ pub async fn save(settings: &AdvancedSettings) -> Result<()> {
// Note: Blocking file write in async function
if let Err(error) = f.write(|f| f.write_all(settings.log_filter.as_bytes())) {
tracing::error!(
?error,
error = std_dyn_err(&error),
?log_filter_path,
"Couldn't write log filter file for IPC service"
);

View File

@@ -1,6 +1,7 @@
//! Module to check the Github repo for new releases
use anyhow::{Context, Result};
use firezone_logging::anyhow_dyn_err;
use rand::{thread_rng, Rng as _};
use semver::Version;
use serde::{Deserialize, Serialize};
@@ -46,7 +47,10 @@ pub async fn checker_task(
tracing::debug!("CheckNetwork");
match check().await {
Ok(release) => fsm.handle_check(release),
Err(error) => tracing::error!(?error, "Couldn't check website for update"),
Err(error) => tracing::error!(
error = anyhow_dyn_err(&error),
"Couldn't check website for update"
),
}
}
Event::WaitInterval => {

View File

@@ -3,6 +3,7 @@ use clap::{Args, Parser};
use firezone_gui_client_common::{
self as common, controller::Failure, deep_link, settings::AdvancedSettings,
};
use firezone_logging::{anyhow_dyn_err, std_dyn_err};
use firezone_telemetry as telemetry;
use std::collections::BTreeMap;
use tracing::instrument;
@@ -53,7 +54,7 @@ pub(crate) fn run() -> Result<()> {
Some(Cmd::OpenDeepLink(deep_link)) => {
let rt = tokio::runtime::Runtime::new()?;
if let Err(error) = rt.block_on(deep_link::open(&deep_link.url)) {
tracing::error!(?error, "Error in `OpenDeepLink`");
tracing::error!(error = anyhow_dyn_err(&error), "Error in `OpenDeepLink`");
}
Ok(())
}
@@ -78,7 +79,7 @@ pub(crate) fn run() -> Result<()> {
// Because of <https://github.com/firezone/firezone/issues/3567>,
// errors returned from `gui::run` may not be logged correctly
tracing::error!(?error);
tracing::error!(error = std_dyn_err(error));
}
Ok(result?)
}
@@ -126,7 +127,7 @@ fn run_gui(cli: Cli) -> Result<()> {
// Make sure errors get logged, at least to stderr
if let Err(error) = &result {
tracing::error!(?error, error_msg = %error);
tracing::error!(error = std_dyn_err(error), error_msg = %error);
common::errors::show_error_dialog(error)?;
}

View File

@@ -18,6 +18,7 @@ use firezone_gui_client_common::{
updates,
};
use firezone_headless_client::LogFilterReloader;
use firezone_logging::{anyhow_dyn_err, std_dyn_err};
use firezone_telemetry as telemetry;
use secrecy::{ExposeSecret as _, SecretString};
use std::{str::FromStr, time::Duration};
@@ -172,7 +173,7 @@ pub(crate) fn run(
tokio::spawn(async move {
if let Err(error) = updates::checker_task(updates_tx, cli.debug_update_check).await
{
tracing::error!(?error, "Error in updates::checker_task");
tracing::error!(error = anyhow_dyn_err(&error), "Error in updates::checker_task");
}
});
@@ -180,7 +181,7 @@ pub(crate) fn run(
let ctlr_tx = ctlr_tx.clone();
tokio::spawn(async move {
if let Err(error) = smoke_test(ctlr_tx).await {
tracing::error!(?error, "Error during smoke test, crashing on purpose so a dev can see our stacktraces");
tracing::error!(error = anyhow_dyn_err(&error), "Error during smoke test, crashing on purpose so a dev can see our stacktraces");
unsafe { sadness_generator::raise_segfault() }
}
});
@@ -257,12 +258,12 @@ pub(crate) fn run(
let exit_code = match task.await {
Err(error) => {
tracing::error!(?error, "run_controller panicked");
tracing::error!(error = std_dyn_err(&error), "run_controller panicked");
telemetry::end_session_with_status(telemetry::SessionStatus::Crashed);
1
}
Ok(Err(error)) => {
tracing::error!(?error, "run_controller returned an error");
tracing::error!(error = std_dyn_err(&error), "run_controller returned an error");
errors::show_error_dialog(&error).unwrap();
telemetry::end_session_with_status(telemetry::SessionStatus::Crashed);
1
@@ -289,7 +290,7 @@ pub(crate) fn run(
let result = setup_inner();
if let Err(error) = &result {
tracing::error!(?error, "Tauri setup failed");
tracing::error!(error, "Tauri setup failed");
}
result
@@ -299,7 +300,10 @@ pub(crate) fn run(
let app = match app {
Ok(x) => x,
Err(error) => {
tracing::error!(?error, "Failed to build Tauri app instance");
tracing::error!(
error = std_dyn_err(&error),
"Failed to build Tauri app instance"
);
#[expect(clippy::wildcard_enum_match_arm)]
match error {
tauri::Error::Runtime(tauri_runtime::Error::CreateWebview(_)) => {
@@ -445,7 +449,10 @@ async fn accept_deep_links(mut server: deep_link::Server, ctlr_tx: CtlrTx) -> Re
.await
.ok();
}
Err(error) => tracing::error!(?error, "error while accepting deep link"),
Err(error) => tracing::error!(
error = anyhow_dyn_err(&error),
"error while accepting deep link"
),
}
// We re-create the named pipe server every time we get a link, because of an oddity in the Windows API.
server = deep_link::Server::new().await?;

View File

@@ -1,6 +1,7 @@
use super::{ControllerRequest, CtlrTx};
use anyhow::{Context, Result};
use firezone_bin_shared::BUNDLE_ID;
use firezone_logging::std_dyn_err;
use tauri::AppHandle;
pub(crate) async fn set_autostart(_enabled: bool) -> Result<()> {
@@ -76,7 +77,7 @@ pub(crate) fn show_clickable_notification(
if let Some(req) = req.take() {
if let Err(error) = tx.blocking_send(req) {
tracing::error!(
?error,
error = std_dyn_err(&error),
"User clicked on notification, but we couldn't tell `Controller`"
);
}

View File

@@ -10,6 +10,7 @@ use firezone_gui_client_common::{
compositor::{self, Image},
system_tray::{AppState, ConnlibState, Entry, Icon, IconBase, Item, Menu},
};
use firezone_logging::anyhow_dyn_err;
use tauri::AppHandle;
type IsMenuItem = dyn tauri::menu::IsMenuItem<tauri::Wry>;
@@ -88,7 +89,10 @@ impl Tray {
self.app
.run_on_main_thread(move || {
if let Err(error) = update(handle, &app, &menu) {
tracing::error!(?error, "Error while updating tray icon");
tracing::error!(
error = anyhow_dyn_err(&error),
"Error while updating tray icon"
);
}
})
.unwrap();

View File

@@ -4,6 +4,7 @@ use firezone_gui_client_common::{
controller::{ControllerRequest, CtlrTx},
logging as common,
};
use firezone_logging::std_dyn_err;
use std::path::PathBuf;
use tauri_plugin_dialog::DialogExt as _;
@@ -12,11 +13,17 @@ pub(crate) async fn clear_logs(managed: tauri::State<'_, Managed>) -> Result<(),
let (tx, rx) = tokio::sync::oneshot::channel();
if let Err(error) = managed.ctlr_tx.send(ControllerRequest::ClearLogs(tx)).await {
// Tauri will only log errors to the JS console for us, so log this ourselves.
tracing::error!(?error, "Error while asking `Controller` to clear logs");
tracing::error!(
error = std_dyn_err(&error),
"Error while asking `Controller` to clear logs"
);
return Err(error.to_string());
}
if let Err(error) = rx.await {
tracing::error!(?error, "Error while awaiting log-clearing operation");
tracing::error!(
error = std_dyn_err(&error),
"Error while awaiting log-clearing operation"
);
return Err(error.to_string());
}
Ok(())

View File

@@ -7,6 +7,7 @@ use firezone_gui_client_common::{
controller::{ControllerRequest, CtlrTx},
settings::{save, AdvancedSettings},
};
use firezone_logging::std_dyn_err;
use std::time::Duration;
use tokio::sync::oneshot;
@@ -57,7 +58,7 @@ pub(crate) async fn get_advanced_settings(
.await
{
tracing::error!(
?error,
error = std_dyn_err(&error),
"couldn't request advanced settings from controller task"
);
}

View File

@@ -2,12 +2,16 @@
use crate::client::gui::Managed;
use firezone_gui_client_common::controller::ControllerRequest;
use firezone_logging::std_dyn_err;
// Tauri requires a `Result` here, maybe in case the managed state can't be retrieved
#[tauri::command]
pub(crate) async fn sign_in(managed: tauri::State<'_, Managed>) -> anyhow::Result<(), String> {
if let Err(error) = managed.ctlr_tx.send(ControllerRequest::SignIn).await {
tracing::error!(?error, "Couldn't request `Controller` to begin signing in");
tracing::error!(
error = std_dyn_err(&error),
"Couldn't request `Controller` to begin signing in"
);
}
Ok(())
}

View File

@@ -7,6 +7,7 @@
use anyhow::Result;
use firezone_bin_shared::platform::DnsControlMethod;
use firezone_logging::anyhow_dyn_err;
use std::net::IpAddr;
#[cfg(target_os = "linux")]
@@ -33,7 +34,10 @@ pub struct DnsController {
impl Drop for DnsController {
fn drop(&mut self) {
if let Err(error) = self.deactivate() {
tracing::error!(?error, "Failed to deactivate DNS control");
tracing::error!(
error = anyhow_dyn_err(&error),
"Failed to deactivate DNS control"
);
}
}
}

View File

@@ -16,6 +16,7 @@
use super::DnsController;
use anyhow::{Context as _, Result};
use firezone_bin_shared::platform::{DnsControlMethod, CREATE_NO_WINDOW, TUNNEL_UUID};
use firezone_logging::std_dyn_err;
use std::{
io::ErrorKind, net::IpAddr, os::windows::process::CommandExt, path::Path, process::Command,
};
@@ -33,12 +34,15 @@ impl DnsController {
let hklm = winreg::RegKey::predef(winreg::enums::HKEY_LOCAL_MACHINE);
if let Err(error) = hklm.delete_subkey(local_nrpt_path().join(NRPT_REG_KEY)) {
if error.kind() != ErrorKind::NotFound {
tracing::error!(?error, "Couldn't delete local NRPT");
tracing::error!(error = std_dyn_err(&error), "Couldn't delete local NRPT");
}
}
if let Err(error) = hklm.delete_subkey(group_nrpt_path().join(NRPT_REG_KEY)) {
if error.kind() != ErrorKind::NotFound {
tracing::error!(?error, "Couldn't delete Group Policy NRPT");
tracing::error!(
error = std_dyn_err(&error),
"Couldn't delete Group Policy NRPT"
);
}
}
refresh_group_policy()?;

View File

@@ -9,6 +9,7 @@ use firezone_bin_shared::{
platform::{tcp_socket_factory, udp_socket_factory, DnsControlMethod},
TunDeviceManager, TOKEN_ENV_KEY,
};
use firezone_logging::{anyhow_dyn_err, std_dyn_err};
use firezone_telemetry::Telemetry;
use futures::{
future::poll_fn,
@@ -116,12 +117,17 @@ pub enum ServerMsg {
}
// All variants are `String` because almost no error type implements `Serialize`
#[derive(Debug, Deserialize, Serialize)]
#[derive(Debug, Deserialize, Serialize, thiserror::Error)]
pub enum Error {
#[error("{0}")]
DeviceId(String),
#[error("{0}")]
LoginUrl(String),
#[error("{0}")]
PortalConnection(String),
#[error("{0}")]
TunnelDevice(String),
#[error("{0}")]
UrlParse(String),
}
@@ -336,7 +342,10 @@ impl<'a> Handler<'a> {
match poll_fn(|cx| self.next_event(cx, signals)).await {
Event::Callback(x) => {
if let Err(error) = self.handle_connlib_cb(x).await {
tracing::error!(?error, "Error while handling connlib callback");
tracing::error!(
error = anyhow_dyn_err(&error),
"Error while handling connlib callback"
);
continue;
}
}
@@ -350,7 +359,10 @@ impl<'a> Handler<'a> {
let _entered =
tracing::error_span!("handle_ipc_msg", msg = %msg_variant).entered();
if let Err(error) = self.handle_ipc_msg(msg).await {
tracing::error!(?error, "Error while handling IPC message from client");
tracing::error!(
error = anyhow_dyn_err(&error),
"Error while handling IPC message from client"
);
continue;
}
}
@@ -359,7 +371,10 @@ impl<'a> Handler<'a> {
break HandlerOk::ClientDisconnected;
}
Event::IpcError(error) => {
tracing::error!(?error, "Error while deserializing IPC message");
tracing::error!(
error = anyhow_dyn_err(&error),
"Error while deserializing IPC message"
);
continue;
}
Event::Terminate => {
@@ -468,7 +483,10 @@ impl<'a> Handler<'a> {
let token = secrecy::SecretString::from(token);
let result = self.connect_to_firezone(&api_url, token);
if let Err(error) = &result {
tracing::error!(?error, "Failed to connect connlib session");
tracing::error!(
error = std_dyn_err(error),
"Failed to connect connlib session"
);
}
self.ipc_tx
.send(&ServerMsg::ConnectResult(result))

View File

@@ -1,5 +1,6 @@
use crate::{IpcClientMsg, IpcServerMsg};
use anyhow::{Context as _, Result};
use firezone_logging::std_dyn_err;
use tokio::io::{ReadHalf, WriteHalf};
use tokio_util::{
bytes::BytesMut,
@@ -145,7 +146,7 @@ pub async fn connect_to_service(id: ServiceId) -> Result<(ClientRead, ClientWrit
}
Err(error) => {
tracing::warn!(
?error,
error = std_dyn_err(&error),
"Couldn't connect to IPC service, will sleep and try again"
);
last_err = Some(error);
@@ -171,6 +172,7 @@ impl platform::Server {
mod tests {
use super::{platform::Server, *};
use anyhow::{bail, ensure, Result};
use firezone_logging::anyhow_dyn_err;
use futures::{SinkExt, StreamExt};
use std::time::Duration;
use tokio::{task::JoinHandle, time::timeout};
@@ -241,14 +243,14 @@ mod tests {
if let Err(panic) = &client_result {
tracing::error!(?panic, "Client panic");
} else if let Ok(Err(error)) = &client_result {
tracing::error!(?error, "Client error");
tracing::error!(error = anyhow_dyn_err(error), "Client error");
}
let server_result = server_task.await;
if let Err(panic) = &server_result {
tracing::error!(?panic, "Server panic");
} else if let Ok(Err(error)) = &server_result {
tracing::error!(?error, "Server error");
tracing::error!(error = anyhow_dyn_err(error), "Server error");
}
if client_result.is_err() || server_result.is_err() {

View File

@@ -1,6 +1,7 @@
use crate::CliCommon;
use anyhow::{bail, Context as _, Result};
use firezone_bin_shared::platform::DnsControlMethod;
use firezone_logging::anyhow_dyn_err;
use futures::future::{self, Either};
use std::{
ffi::{c_void, OsString},
@@ -132,7 +133,10 @@ fn service_run(arguments: Vec<OsString>) {
let (handle, log_filter_reloader) =
super::setup_logging(None).expect("Should be able to set up logging");
if let Err(error) = fallible_service_run(arguments, handle, log_filter_reloader) {
tracing::error!(?error, "`fallible_windows_service_run` returned an error");
tracing::error!(
error = anyhow_dyn_err(&error),
"`fallible_windows_service_run` returned an error"
);
}
}
@@ -208,7 +212,7 @@ fn fallible_service_run(
// Windows that we're shutting down.
let result = rt.block_on(service_run_async(&log_filter_reloader, shutdown_rx));
if let Err(error) = &result {
tracing::error!(?error);
tracing::error!(error = anyhow_dyn_err(error));
}
// Drop the logging handle so it flushes the logs before we let Windows kill our process.

View File

@@ -12,6 +12,7 @@ use firezone_bin_shared::{
use firezone_headless_client::{
device_id, signals, CallbackHandler, CliCommon, ConnlibMsg, DnsController,
};
use firezone_logging::anyhow_dyn_err;
use firezone_telemetry::Telemetry;
use futures::{FutureExt as _, StreamExt as _};
use phoenix_channel::get_user_agent;
@@ -321,10 +322,10 @@ fn main() -> Result<()> {
};
if let Err(error) = dns_notifier.close() {
tracing::error!(?error, "DNS notifier")
tracing::error!(error = anyhow_dyn_err(&error), "DNS notifier")
}
if let Err(error) = network_notifier.close() {
tracing::error!(?error, "network notifier");
tracing::error!(error = anyhow_dyn_err(&error), "network notifier");
}
telemetry.stop().await; // Stop telemetry before dropping session. `connlib` needs to be active for this, otherwise we won't be able to resolve the DNS name for sentry.