1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-08-09 04:22:45 +03:00

Log more errors and setup Sentry integration

This commit is contained in:
Quentin Gliech
2023-01-30 17:28:59 +01:00
parent 694e97e96c
commit 875025467e
37 changed files with 439 additions and 16 deletions

221
Cargo.lock generated
View File

@@ -18,7 +18,16 @@ version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
dependencies = [
"gimli",
"gimli 0.26.2",
]
[[package]]
name = "addr2line"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"
dependencies = [
"gimli 0.27.1",
]
[[package]]
@@ -711,6 +720,21 @@ dependencies = [
"syn",
]
[[package]]
name = "backtrace"
version = "0.3.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca"
dependencies = [
"addr2line 0.19.0",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object 0.30.3",
"rustc-demangle",
]
[[package]]
name = "base16ct"
version = "0.1.1"
@@ -1169,7 +1193,7 @@ dependencies = [
"cranelift-codegen-shared",
"cranelift-entity",
"cranelift-isle",
"gimli",
"gimli 0.26.2",
"hashbrown",
"log",
"regalloc2",
@@ -1470,6 +1494,16 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaa37046cc0f6c3cc6090fbdbf73ef0b8ef4cfcc37f6befc0020f63e8cf121e1"
[[package]]
name = "debugid"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d"
dependencies = [
"serde",
"uuid",
]
[[package]]
name = "der"
version = "0.6.1"
@@ -1988,6 +2022,12 @@ dependencies = [
"stable_deref_trait",
]
[[package]]
name = "gimli"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec"
[[package]]
name = "globset"
version = "0.4.10"
@@ -2745,6 +2785,9 @@ dependencies = [
"rand 0.8.5",
"rand_chacha 0.3.1",
"rustls",
"sentry",
"sentry-tower",
"sentry-tracing",
"serde_json",
"serde_yaml",
"sqlx",
@@ -3444,6 +3487,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "object"
version = "0.30.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.17.0"
@@ -3658,6 +3710,17 @@ dependencies = [
"num-traits",
]
[[package]]
name = "os_info"
version = "3.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4750134fb6a5d49afc80777394ad5d95b04bc12068c6abb92fae8f43817270f"
dependencies = [
"log",
"serde",
"winapi",
]
[[package]]
name = "os_str_bytes"
version = "6.4.1"
@@ -4691,6 +4754,116 @@ version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
[[package]]
name = "sentry"
version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6097dc270a9c4555c5d6222ed243eaa97ff38e29299ed7c5cb36099033c604e"
dependencies = [
"httpdate",
"reqwest",
"rustls",
"sentry-backtrace",
"sentry-contexts",
"sentry-core",
"sentry-panic",
"sentry-tower",
"tokio",
"ureq",
"webpki-roots",
]
[[package]]
name = "sentry-backtrace"
version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d92d1e4d591534ae4f872d6142f3b500f4ffc179a6aed8a3e86c7cc96d10a6a"
dependencies = [
"backtrace",
"once_cell",
"regex",
"sentry-core",
]
[[package]]
name = "sentry-contexts"
version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3afa877b1898ff67dd9878cf4bec4e53cef7d3be9f14b1fc9e4fcdf36f8e4259"
dependencies = [
"hostname",
"libc",
"os_info",
"rustc_version",
"sentry-core",
"uname",
]
[[package]]
name = "sentry-core"
version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc43eb7e4e3a444151a0fe8a0e9ce60eabd905dae33d66e257fa26f1b509c1bd"
dependencies = [
"once_cell",
"rand 0.8.5",
"sentry-types",
"serde",
"serde_json",
]
[[package]]
name = "sentry-panic"
version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccab4fab11e3e63c45f4524bee2e75cde39cdf164cb0b0cbe6ccd1948ceddf66"
dependencies = [
"sentry-backtrace",
"sentry-core",
]
[[package]]
name = "sentry-tower"
version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "849fbf257de067f41ae1e2f9253538ceaedd79739e79800c4169b463e9160f19"
dependencies = [
"http",
"pin-project",
"sentry-core",
"tower-layer",
"tower-service",
"url",
]
[[package]]
name = "sentry-tracing"
version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46ebf58c2bd1d97152c316ff170ee736c59a16967738aeb8ed0d79b80e3713ae"
dependencies = [
"sentry-core",
"tracing-core",
"tracing-subscriber",
]
[[package]]
name = "sentry-types"
version = "0.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63708ec450b6bdcb657af760c447416d69c38ce421f34e5e2e9ce8118410bc7"
dependencies = [
"debugid",
"getrandom 0.2.8",
"hex",
"serde",
"serde_json",
"thiserror",
"time 0.3.17",
"url",
"uuid",
]
[[package]]
name = "serde"
version = "1.0.152"
@@ -5681,6 +5854,15 @@ dependencies = [
"uuid",
]
[[package]]
name = "uname"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8"
dependencies = [
"libc",
]
[[package]]
name = "uncased"
version = "0.9.7"
@@ -5816,6 +5998,21 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "ureq"
version = "2.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "338b31dd1314f68f3aabf3ed57ab922df95ffcd902476ca7ba3c4ce7b908c46d"
dependencies = [
"base64 0.13.1",
"log",
"once_cell",
"rustls",
"url",
"webpki",
"webpki-roots",
]
[[package]]
name = "url"
version = "2.3.1"
@@ -5839,6 +6036,10 @@ name = "uuid"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c"
dependencies = [
"getrandom 0.2.8",
"serde",
]
[[package]]
name = "valuable"
@@ -5986,7 +6187,7 @@ dependencies = [
"indexmap",
"libc",
"log",
"object",
"object 0.29.0",
"once_cell",
"paste",
"psm",
@@ -6064,9 +6265,9 @@ dependencies = [
"cranelift-frontend",
"cranelift-native",
"cranelift-wasm",
"gimli",
"gimli 0.26.2",
"log",
"object",
"object 0.29.0",
"target-lexicon",
"thiserror",
"wasmparser",
@@ -6081,10 +6282,10 @@ checksum = "e5a2a5f0fb93aa837a727a48dd1076e8a9f882cc2fee20b433c04a18740ff63b"
dependencies = [
"anyhow",
"cranelift-entity",
"gimli",
"gimli 0.26.2",
"indexmap",
"log",
"object",
"object 0.29.0",
"serde",
"target-lexicon",
"thiserror",
@@ -6111,14 +6312,14 @@ version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01c78f9fb2922dbb5a95f009539d4badb44866caeeb53d156bf2cf4d683c3afd"
dependencies = [
"addr2line",
"addr2line 0.17.0",
"anyhow",
"bincode",
"cfg-if",
"cpp_demangle",
"gimli",
"gimli 0.26.2",
"log",
"object",
"object 0.29.0",
"rustc-demangle",
"serde",
"target-lexicon",

View File

@@ -72,6 +72,17 @@ pub enum Credentials {
}
impl Credentials {
/// Get the `client_id` of the credentials
#[must_use]
pub fn client_id(&self) -> &str {
match self {
Credentials::None { client_id }
| Credentials::ClientSecretBasic { client_id, .. }
| Credentials::ClientSecretPost { client_id, .. }
| Credentials::ClientAssertionJwtBearer { client_id, .. } => client_id,
}
}
pub async fn fetch<E>(
&self,
repo: &mut impl RepositoryAccess<Error = E>,
@@ -217,6 +228,14 @@ pub struct ClientAuthorization<F = ()> {
pub form: Option<F>,
}
impl<F> ClientAuthorization<F> {
/// Get the `client_id` from the credentials.
#[must_use]
pub fn client_id(&self) -> &str {
self.credentials.client_id()
}
}
#[derive(Debug)]
pub enum ClientAuthorizationError {
InvalidHeader,

View File

@@ -23,6 +23,23 @@ pub struct FancyError {
context: ErrorContext,
}
impl std::fmt::Display for FancyError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let code = self.context.code().unwrap_or("Internal error");
match (self.context.description(), self.context.details()) {
(Some(description), Some(details)) => {
write!(f, "{code}: {description} ({details})")
}
(Some(message), None) | (None, Some(message)) => {
write!(f, "{code}: {message}")
}
(None, None) => {
write!(f, "{code}")
}
}
}
}
impl<E: std::fmt::Debug + std::fmt::Display> From<E> for FancyError {
fn from(err: E) -> Self {
let context = ErrorContext::new()

View File

@@ -39,6 +39,9 @@ opentelemetry-zipkin = { version = "0.16.0", features = ["opentelemetry-http"],
opentelemetry-http = { version = "0.7.0", features = ["tokio", "hyper"], optional = true }
opentelemetry-prometheus = { version = "0.11.0", optional = true }
prometheus = { version = "0.13.3", optional = true }
sentry = { version = "0.29.2", default-features = false, features = ["backtrace", "contexts", "panic", "reqwest", "rustls", "tower"] }
sentry-tracing = "0.29.2"
sentry-tower = { version = "0.29.2", features = ["http"] }
mas-config = { path = "../config" }
mas-email = { path = "../email" }

View File

@@ -60,12 +60,17 @@ async fn try_main() -> anyhow::Result<()> {
// Don't fill the telemetry layer for now, we want to configure it based on the
// app config, so we need to delay that a bit
let (telemetry_layer, handle) = reload::Layer::new(None);
let (telemetry_layer, telemetry_handle) = reload::Layer::new(None);
// We only want "INFO" level spans to go through OpenTelemetry
let telemetry_layer = telemetry_layer.with_filter(LevelFilter::INFO);
// Don't fill the Sentry layer for now, we want to configure it based on the
// app config, so we need to delay that a bit
let (sentry_layer, sentry_handle) = reload::Layer::new(None);
let subscriber = Registry::default()
.with(telemetry_layer)
.with(sentry_layer)
.with(filter_layer)
.with(fmt_layer);
subscriber
@@ -88,13 +93,19 @@ async fn try_main() -> anyhow::Result<()> {
// Falling back to default.
let telemetry_config: TelemetryConfig = opts.load_config().unwrap_or_default();
// Setup Sentry
let sentry = sentry::init(telemetry_config.sentry.dsn.as_deref());
if sentry.is_enabled() {
sentry_handle.reload(sentry_tracing::layer())?;
}
// Setup OpenTelemtry tracing and metrics
let (tracer, _meter) = telemetry::setup(&telemetry_config)
.await
.context("failed to setup opentelemetry")?;
if let Some(tracer) = tracer {
// Now we can swap out the actual opentelemetry tracing layer
handle.reload(
telemetry_handle.reload(
tracing_opentelemetry::layer()
.with_tracer(tracer)
.with_tracked_inactivity(false),

View File

@@ -31,6 +31,7 @@ use mas_spa::ViteManifestService;
use mas_templates::Templates;
use opentelemetry::KeyValue;
use rustls::ServerConfig;
use sentry_tower::{NewSentryLayer, SentryHttpLayer};
use tower::Layer;
use tower_http::{compression::CompressionLayer, services::ServeDir};
@@ -119,6 +120,8 @@ where
}
router
.layer(SentryHttpLayer::new())
.layer(NewSentryLayer::new_from_top())
.layer(trace_layer)
.layer(CompressionLayer::new())
.with_state(state)

View File

@@ -257,6 +257,19 @@ pub struct MetricsConfig {
pub exporter: MetricsExporterConfig,
}
fn sentry_dsn_example() -> &'static str {
"https://public@host:port/1"
}
/// Configuration related to the Sentry integration
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
pub struct SentryConfig {
/// Sentry DSN
#[schemars(url, example = "sentry_dsn_example")]
#[serde(default)]
pub dsn: Option<String>,
}
/// Configuration related to sending monitoring data
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
pub struct TelemetryConfig {
@@ -267,6 +280,10 @@ pub struct TelemetryConfig {
/// Configuration related to exporting metrics
#[serde(default)]
pub metrics: MetricsConfig,
/// Configuration related to the Sentry integration
#[serde(default)]
pub sentry: SentryConfig,
}
#[async_trait]

View File

@@ -64,6 +64,7 @@ struct LoginTypes {
flows: Vec<LoginType>,
}
#[tracing::instrument(name = "handlers.compat.login.get", skip_all)]
pub(crate) async fn get() -> impl IntoResponse {
let res = LoginTypes {
flows: vec![
@@ -190,7 +191,7 @@ impl IntoResponse for RouteError {
}
}
#[tracing::instrument(skip_all, err)]
#[tracing::instrument(name = "handlers.compat.login.post", skip_all, err)]
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -51,6 +51,12 @@ pub struct Params {
action: Option<CompatLoginSsoAction>,
}
#[tracing::instrument(
name = "handlers.compat.login_sso_complete.get",
fields(compat_sso_login.id = %id),
skip_all,
err,
)]
pub async fn get(
mut rng: BoxRng,
clock: BoxClock,
@@ -113,6 +119,12 @@ pub async fn get(
Ok((cookie_jar, Html(content)).into_response())
}
#[tracing::instrument(
name = "handlers.compat.login_sso_complete.post",
fields(compat_sso_login.id = %id),
skip_all,
err,
)]
pub async fn post(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -55,6 +55,7 @@ impl IntoResponse for RouteError {
}
}
#[tracing::instrument(name = "handlers.compat.login_sso_redirect.get", skip_all, err)]
pub async fn get(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -65,6 +65,7 @@ impl IntoResponse for RouteError {
}
}
#[tracing::instrument(name = "handlers.compat.logout.post", skip_all, err)]
pub(crate) async fn post(
clock: BoxClock,
mut repo: BoxRepository,

View File

@@ -85,6 +85,7 @@ pub struct ResponseBody {
expires_in_ms: Duration,
}
#[tracing::instrument(name = "handlers.compat.refresh.post", skip_all, err)]
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -75,6 +75,12 @@ impl_from_error_for_route!(mas_policy::EvaluationError);
impl_from_error_for_route!(super::callback::IntoCallbackDestinationError);
impl_from_error_for_route!(super::callback::CallbackDestinationError);
#[tracing::instrument(
name = "handlers.oauth2.authorization_complete.get",
fields(grant.id = %grant_id),
skip_all,
err,
)]
pub(crate) async fn get(
rng: BoxRng,
clock: BoxClock,

View File

@@ -128,6 +128,12 @@ fn resolve_response_mode(
}
}
#[tracing::instrument(
name = "handlers.oauth2.authorization.get",
fields(client.id = %params.auth.client_id),
skip_all,
err,
)]
#[allow(clippy::too_many_lines)]
pub(crate) async fn get(
mut rng: BoxRng,

View File

@@ -71,6 +71,12 @@ impl IntoResponse for RouteError {
}
}
#[tracing::instrument(
name = "handlers.oauth2.consent.get",
fields(grant.id = %grant_id),
skip_all,
err,
)]
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,
@@ -125,6 +131,12 @@ pub(crate) async fn get(
}
}
#[tracing::instrument(
name = "handlers.oauth2.consent.post",
fields(grant.id = %grant_id),
skip_all,
err,
)]
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -26,6 +26,7 @@ use oauth2_types::{
scope,
};
#[tracing::instrument(name = "handlers.oauth2.discovery.get", skip_all)]
#[allow(clippy::too_many_lines)]
pub(crate) async fn get(
State(key_store): State<Keystore>,

View File

@@ -120,6 +120,12 @@ const INACTIVE: IntrospectionResponse = IntrospectionResponse {
const API_SCOPE: ScopeToken = ScopeToken::from_static("urn:matrix:org.matrix.msc2967.client:api:*");
#[tracing::instrument(
name = "handlers.oauth2.introspection.post",
fields(client.id = client_authorization.client_id()),
skip_all,
err,
)]
#[allow(clippy::too_many_lines)]
pub(crate) async fn post(
clock: BoxClock,

View File

@@ -15,6 +15,7 @@
use axum::{extract::State, response::IntoResponse, Json};
use mas_keystore::Keystore;
#[tracing::instrument(name = "handlers.oauth2.keys.get", skip_all)]
pub(crate) async fn get(State(key_store): State<Keystore>) -> impl IntoResponse {
let jwks = key_store.public_jwks();
Json(jwks)

View File

@@ -103,7 +103,7 @@ impl IntoResponse for RouteError {
}
}
#[tracing::instrument(skip_all, err)]
#[tracing::instrument(name = "handlers.oauth2.registration.post", skip_all, err)]
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -155,7 +155,12 @@ impl_from_error_for_route!(mas_jose::claims::ClaimError);
impl_from_error_for_route!(mas_jose::claims::TokenHashError);
impl_from_error_for_route!(mas_jose::jwt::JwtSignatureError);
#[tracing::instrument(skip_all, err)]
#[tracing::instrument(
name = "handlers.oauth2.token.post",
fields(client.id = client_authorization.client_id()),
skip_all,
err,
)]
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -95,6 +95,7 @@ impl IntoResponse for RouteError {
}
}
#[tracing::instrument(name = "handlers.oauth2.userinfo.get", skip_all, err)]
pub async fn get(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -35,6 +35,7 @@ fn jrd() -> mime::Mime {
"application/jrd+json".parse().unwrap()
}
#[tracing::instrument(name = "handlers.oauth2.webfinger.get", skip_all)]
pub(crate) async fn get(
Query(params): Query<Params>,
State(url_builder): State<UrlBuilder>,

View File

@@ -55,6 +55,12 @@ impl IntoResponse for RouteError {
}
}
#[tracing::instrument(
name = "handlers.upstream_oauth2.authorize.get",
fields(upstream_oauth_provider.id = %provider_id),
skip_all,
err,
)]
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -117,6 +117,12 @@ impl IntoResponse for RouteError {
}
}
#[tracing::instrument(
name = "handlers.upstream_oauth2.callback.get",
fields(upstream_oauth_provider.id = %provider_id),
skip_all,
err,
)]
#[allow(clippy::too_many_lines, clippy::too_many_arguments)]
pub(crate) async fn get(
mut rng: BoxRng,

View File

@@ -91,6 +91,12 @@ pub(crate) enum FormData {
Login,
}
#[tracing::instrument(
name = "handlers.upstream_oauth2.link.get",
fields(upstream_oauth_link.id = %link_id),
skip_all,
err,
)]
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,
@@ -207,6 +213,12 @@ pub(crate) async fn get(
Ok((cookie_jar, Html(render)))
}
#[tracing::instrument(
name = "handlers.upstream_oauth2.link.post",
fields(upstream_oauth_link.id = %link_id),
skip_all,
err,
)]
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -36,6 +36,7 @@ pub struct EmailForm {
email: String,
}
#[tracing::instrument(name = "handlers.views.account_email_add.get", skip_all, err)]
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,
@@ -64,6 +65,7 @@ pub(crate) async fn get(
Ok((cookie_jar, Html(content)).into_response())
}
#[tracing::instrument(name = "handlers.views.account_email_add.post", skip_all, err)]
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -48,6 +48,7 @@ pub enum ManagementForm {
Remove { id: String },
}
#[tracing::instrument(name = "handlers.views.account_email_list.get", skip_all, err)]
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,
@@ -121,6 +122,7 @@ async fn start_email_verification<E: std::error::Error + Send + Sync + 'static>(
Ok(())
}
#[tracing::instrument(name = "handlers.views.account_email_list.post", skip_all, err)]
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -36,6 +36,12 @@ pub struct CodeForm {
code: String,
}
#[tracing::instrument(
name = "handlers.views.account_email_verify.get",
fields(user_email.id = %id),
skip_all,
err,
)]
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,
@@ -79,6 +85,12 @@ pub(crate) async fn get(
Ok((cookie_jar, Html(content)).into_response())
}
#[tracing::instrument(
name = "handlers.views.account_email_verify.post",
fields(user_email.id = %id),
skip_all,
err,
)]
pub(crate) async fn post(
clock: BoxClock,
mut repo: BoxRepository,

View File

@@ -29,6 +29,7 @@ use mas_storage::{
};
use mas_templates::{AccountContext, TemplateContext, Templates};
#[tracing::instrument(name = "handlers.views.account.get", skip_all, err)]
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -43,6 +43,7 @@ pub struct ChangeForm {
new_password_confirm: String,
}
#[tracing::instrument(name = "handlers.views.account_password.get", skip_all, err)]
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,
@@ -80,6 +81,7 @@ async fn render(
Ok((cookie_jar, Html(content)).into_response())
}
#[tracing::instrument(name = "handlers.views.account_password.post", skip_all, err)]
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -23,6 +23,7 @@ use mas_router::UrlBuilder;
use mas_storage::{BoxClock, BoxRepository, BoxRng};
use mas_templates::{IndexContext, TemplateContext, Templates};
#[tracing::instrument(name = "handlers.views.index.get", skip_all, err)]
pub async fn get(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -48,6 +48,7 @@ impl ToFormState for LoginForm {
type Field = LoginFormField;
}
#[tracing::instrument(name = "handlers.views.login.get", skip_all, err)]
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,
@@ -79,6 +80,7 @@ pub(crate) async fn get(
}
}
#[tracing::instrument(name = "handlers.views.login.post", skip_all, err)]
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -22,6 +22,7 @@ use mas_keystore::Encrypter;
use mas_router::{PostAuthAction, Route};
use mas_storage::{user::BrowserSessionRepository, BoxClock, BoxRepository};
#[tracing::instrument(name = "handlers.views.logout.post", skip_all, err)]
pub(crate) async fn post(
clock: BoxClock,
mut repo: BoxRepository,

View File

@@ -40,6 +40,7 @@ pub(crate) struct ReauthForm {
password: String,
}
#[tracing::instrument(name = "handlers.views.reauth.get", skip_all, err)]
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,
@@ -76,6 +77,7 @@ pub(crate) async fn get(
Ok((cookie_jar, Html(content)).into_response())
}
#[tracing::instrument(name = "handlers.views.reauth.post", skip_all, err)]
pub(crate) async fn post(
mut rng: BoxRng,
clock: BoxClock,

View File

@@ -58,6 +58,7 @@ impl ToFormState for RegisterForm {
type Field = RegisterFormField;
}
#[tracing::instrument(name = "handlers.views.register.get", skip_all, err)]
pub(crate) async fn get(
mut rng: BoxRng,
clock: BoxClock,
@@ -88,6 +89,7 @@ pub(crate) async fn get(
}
}
#[tracing::instrument(name = "handlers.views.register.post", skip_all, err)]
#[allow(clippy::too_many_lines, clippy::too_many_arguments)]
pub(crate) async fn post(
mut rng: BoxRng,

View File

@@ -912,10 +912,27 @@ impl ErrorContext {
}
/// Add the error details to the context
#[allow(dead_code)]
#[must_use]
pub fn with_details(mut self, details: String) -> Self {
self.details = Some(details);
self
}
/// Get the error code, if any
#[must_use]
pub fn code(&self) -> Option<&'static str> {
self.code
}
/// Get the description, if any
#[must_use]
pub fn description(&self) -> Option<&str> {
self.description.as_deref()
}
/// Get the details, if any
#[must_use]
pub fn details(&self) -> Option<&str> {
self.details.as_deref()
}
}

View File

@@ -173,6 +173,9 @@
"metrics": {
"exporter": "none"
},
"sentry": {
"dsn": null
},
"tracing": {
"exporter": "none",
"propagators": []
@@ -1578,6 +1581,21 @@
}
}
},
"SentryConfig": {
"description": "Configuration related to the Sentry integration",
"type": "object",
"properties": {
"dsn": {
"description": "Sentry DSN",
"default": null,
"examples": [
"https://public@host:port/1"
],
"type": "string",
"format": "uri"
}
}
},
"TelemetryConfig": {
"description": "Configuration related to sending monitoring data",
"type": "object",
@@ -1593,6 +1611,17 @@
}
]
},
"sentry": {
"description": "Configuration related to the Sentry integration",
"default": {
"dsn": null
},
"allOf": [
{
"$ref": "#/definitions/SentryConfig"
}
]
},
"tracing": {
"description": "Configuration related to exporting traces",
"default": {