Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: add error traces #145

Merged
merged 3 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions apps/server/src/authentication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header,
use secrecy::{ExposeSecret, Secret};
use serde::{Deserialize, Serialize};
use time::{Duration, OffsetDateTime};
use tracing::trace;

use crate::state::SharedState;

Expand Down Expand Up @@ -48,6 +47,7 @@ where
}

impl IntoResponse for Error {
#[tracing::instrument(name = "authentication error")]
fn into_response(self) -> Response {
match self {
Self::InvalidToken(_) | Self::NoToken => (StatusCode::BAD_REQUEST, "Invalid token"),
Expand All @@ -56,6 +56,7 @@ impl IntoResponse for Error {
}
}

#[tracing::instrument(name = "create jwt token", skip(secret))]
pub fn create_jwt(
store_hash: &str,
secret: &Secret<String>,
Expand All @@ -82,8 +83,6 @@ pub fn decode_token(token: &str, secret: &Secret<String>) -> Result<AuthClaims,
validation.validate_aud = false;
let decoded = decode::<AuthClaims>(token, &key, &validation).map_err(Error::InvalidToken)?;

trace!(?decoded, "token decoded");

Ok(decoded.claims)
}

Expand Down
24 changes: 12 additions & 12 deletions apps/server/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use uuid::Uuid;

use crate::bigcommerce::{script::Script, store::APIToken};

#[tracing::instrument(name = "Write store credentials to database", skip(store, pool))]
#[tracing::instrument(name = "write store credentials to database", skip(store, pool))]
pub async fn write_store_credentials(store: &APIToken, pool: &PgPool) -> Result<(), sqlx::Error> {
sqlx::query!(
r#"
Expand All @@ -27,7 +27,7 @@ pub async fn write_store_credentials(store: &APIToken, pool: &PgPool) -> Result<
Ok(())
}

#[tracing::instrument(name = "Read store credentials from database", skip(store_hash, pool))]
#[tracing::instrument(name = "read store credentials from database", skip(store_hash, pool))]
pub async fn read_store_credentials(
store_hash: &str,
pool: &PgPool,
Expand All @@ -48,7 +48,7 @@ pub async fn read_store_credentials(
}

#[tracing::instrument(
name = "Write store is uninstalled in database",
name = "write store is uninstalled in database",
skip(store_hash, pool)
)]
pub async fn write_store_as_uninstalled(
Expand All @@ -70,7 +70,7 @@ pub async fn write_store_as_uninstalled(
}

#[tracing::instrument(
name = "Write store published status in database",
name = "write store published status in database",
skip(store_hash, pool)
)]
pub async fn write_store_published(
Expand All @@ -93,7 +93,7 @@ pub async fn write_store_published(
Ok(())
}

#[tracing::instrument(name = "Write unpublish feedback to database", skip(store_hash, pool))]
#[tracing::instrument(name = "write unpublish feedback to database", skip(store_hash, pool))]
pub async fn write_unpublish_feedback(
store_hash: &str,
reason: &str,
Expand Down Expand Up @@ -123,7 +123,7 @@ pub struct StoreStatus {
}

#[tracing::instrument(
name = "Read store published status from database",
name = "read store published status from database",
skip(store_hash, pool)
)]
pub async fn read_store_published(
Expand Down Expand Up @@ -175,7 +175,7 @@ impl WidgetConfiguration {
}

#[tracing::instrument(
name = "Write widget configuration to database",
name = "write widget configuration to database",
skip(store_hash, db_pool)
)]
pub async fn write_widget_configuration(
Expand Down Expand Up @@ -204,7 +204,7 @@ pub async fn write_widget_configuration(
}

#[tracing::instrument(
name = "Read widget configuration from database",
name = "read widget configuration from database",
skip(store_hash, db_pool)
)]
pub async fn read_widget_configuration(
Expand Down Expand Up @@ -255,7 +255,7 @@ pub struct CharityEvent {
event: CharityEventType,
}

#[tracing::instrument(name = "Write charity visit event to database", skip(db_pool))]
#[tracing::instrument(name = "write charity visit event to database", skip(db_pool))]
pub async fn write_charity_visited_event(
event: &CharityEvent,
db_pool: &PgPool,
Expand Down Expand Up @@ -328,7 +328,7 @@ pub fn store_hash_field_from_str(store_hash: &str) -> Option<&str> {
}
}

#[tracing::instrument(name = "Write widget event to database", skip(db_pool))]
#[tracing::instrument(name = "write widget event to database", skip(db_pool))]
pub async fn write_widget_event(event: &WidgetEvent, db_pool: &PgPool) -> Result<(), sqlx::Error> {
sqlx::query!(
r#"
Expand All @@ -352,7 +352,7 @@ pub struct FeedbackForm {
message: String,
}

#[tracing::instrument(name = "Write feedback to database", skip(db_pool))]
#[tracing::instrument(name = "write feedback to database", skip(db_pool))]
pub async fn write_general_feedback(
data: &FeedbackForm,
db_pool: &PgPool,
Expand Down Expand Up @@ -396,7 +396,7 @@ pub struct UniversalConfiguratorEvent {
event_type: UniversalConfiguratorEventType,
}

#[tracing::instrument(name = "Write universal widget event to database", skip(db_pool))]
#[tracing::instrument(name = "write universal widget event to database", skip(db_pool))]
pub async fn write_universal_widget_event(
data: &UniversalConfiguratorEvent,
db_pool: &PgPool,
Expand Down
4 changes: 2 additions & 2 deletions apps/server/src/liq_pay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl HttpAPI {
}
}

#[tracing::instrument(name = "Generate payload", skip(self))]
#[tracing::instrument(name = "generate request payload", skip(self))]
pub fn generate_request_payload(
&self,
query: InputQuery,
Expand Down Expand Up @@ -118,7 +118,7 @@ impl HttpAPI {
}
}

#[tracing::instrument(name = "Generate LiqPay link", skip(self))]
#[tracing::instrument(name = "generate link", skip(self))]
pub fn link(&self, request: CheckoutRequest) -> String {
let data = serde_json::to_string(&request).unwrap();
let data = encoder.encode(data);
Expand Down
11 changes: 5 additions & 6 deletions apps/server/src/routes/bigcommerce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum InstallError {
}

impl IntoResponse for InstallError {
#[tracing::instrument(name = "install error")]
fn into_response(self) -> Response {
match self {
Self::UnexpectedError(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
Expand All @@ -42,7 +43,7 @@ impl IntoResponse for InstallError {
}

#[tracing::instrument(
name = "Process install request",
name = "process install request",
skip(query, bigcommerce_client, db_pool, jwt_secret, base_url),
fields(context=tracing::field::Empty, user_email=tracing::field::Empty)
)]
Expand Down Expand Up @@ -107,6 +108,7 @@ enum LoadError {
}

impl IntoResponse for LoadError {
#[tracing::instrument(name = "load error")]
fn into_response(self) -> Response {
match self {
Self::NotStoreOwnerError | Self::InvalidCredentials(_) => StatusCode::UNAUTHORIZED,
Expand All @@ -117,7 +119,7 @@ impl IntoResponse for LoadError {
}

#[tracing::instrument(
name = "Process load request",
name = "load request",
skip(query, bigcommerce_client, base_url, jwt_secret)
)]
async fn load(
Expand All @@ -144,10 +146,7 @@ async fn load(
Ok(Redirect::to(&generate_dashboard_url(&base_url, &jwt, store_hash)).into_response())
}

#[tracing::instrument(
name = "Process uninstall request",
skip(query, bigcommerce_client, db_pool)
)]
#[tracing::instrument(name = "uninstall request", skip(query, bigcommerce_client, db_pool))]
async fn uninstall(
Query(query): Query<LoadQuery>,
State(AppState {
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/routes/pay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub fn router() -> Router<SharedState> {
Router::new().route("/", get(pay))
}

#[tracing::instrument(name = "Process pay request", skip(query, liq_pay_client))]
#[tracing::instrument(name = "pay request", skip(query, liq_pay_client))]
async fn pay(
Query(query): Query<InputQuery>,
State(AppState { liq_pay_client, .. }): State<AppState>,
Expand Down
30 changes: 16 additions & 14 deletions apps/server/src/routes/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,15 @@ enum ConfigurationError {
}

impl IntoResponse for ConfigurationError {
#[tracing::instrument(name = "configuration error")]
fn into_response(self) -> axum::response::Response {
match self {
Self::UnexpectedError(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
}
}
}

#[tracing::instrument(name = "Save widget configuration", skip(auth, db_pool))]
#[tracing::instrument(name = "save widget configuration", skip(auth, db_pool))]
async fn save_widget_configuration(
auth: AuthClaims,
State(AppState { db_pool, .. }): State<AppState>,
Expand All @@ -74,7 +75,7 @@ async fn save_widget_configuration(
Ok(StatusCode::OK.into_response())
}

#[tracing::instrument(name = "Get widget configuration", skip(auth, db_pool))]
#[tracing::instrument(name = "get widget configuration", skip(auth, db_pool))]
async fn get_widget_configuration(
auth: AuthClaims,
State(AppState { db_pool, .. }): State<AppState>,
Expand All @@ -95,6 +96,7 @@ enum PublishError {
}

impl IntoResponse for PublishError {
#[tracing::instrument(name = "publish error")]
fn into_response(self) -> Response {
match self {
Self::UnexpectedError(_) => StatusCode::INTERNAL_SERVER_ERROR,
Expand All @@ -104,7 +106,7 @@ impl IntoResponse for PublishError {
}

#[tracing::instrument(
name = "Publish the widget",
name = "publish widget",
skip(auth, db_pool, base_url, bigcommerce_client)
)]
async fn publish_widget(
Expand Down Expand Up @@ -159,7 +161,7 @@ struct Feedback {
}

#[tracing::instrument(
name = "Remove widget",
name = "remove widget",
skip(auth, db_pool, bigcommerce_client, feedback)
)]
async fn remove_widget(
Expand Down Expand Up @@ -199,7 +201,7 @@ async fn remove_widget(
Ok(StatusCode::OK.into_response())
}

#[tracing::instrument(name = "Preview widget", skip(auth, db_pool, bigcommerce_client))]
#[tracing::instrument(name = "preview widget", skip(auth, db_pool, bigcommerce_client))]
async fn preview_widget(
auth: AuthClaims,
State(AppState {
Expand All @@ -224,7 +226,7 @@ async fn preview_widget(
Ok(Json(store_information).into_response())
}

#[tracing::instrument(name = "Get widget status", skip(auth, db_pool))]
#[tracing::instrument(name = "get widget status", skip(auth, db_pool))]
async fn get_published_status(
auth: AuthClaims,
State(AppState { db_pool, .. }): State<AppState>,
Expand All @@ -239,49 +241,49 @@ async fn get_published_status(
Ok(Json(store_status).into_response())
}

#[tracing::instrument(name = "Log charity event", skip(db_pool))]
#[tracing::instrument(name = "log charity event", skip(db_pool))]
async fn log_charity_event(
Query(event): Query<CharityEvent>,
State(AppState { db_pool, .. }): State<AppState>,
) -> Response {
if let Err(error) = write_charity_visited_event(&event, &db_pool).await {
tracing::warn!("Error while saving event {}", error);
tracing::warn!("error while saving event {}", error);
};

StatusCode::OK.into_response()
}

#[tracing::instrument(name = "Save feedback form", skip(db_pool))]
#[tracing::instrument(name = "save feedback form", skip(db_pool))]
async fn submit_general_feedback(
Query(event): Query<FeedbackForm>,
State(AppState { db_pool, .. }): State<AppState>,
) -> Response {
if let Err(error) = write_general_feedback(&event, &db_pool).await {
tracing::warn!("Error while saving event {}", error);
tracing::warn!("error while saving event {}", error);
};

StatusCode::OK.into_response()
}

#[tracing::instrument(name = "Save universal configurator event", skip(db_pool))]
#[tracing::instrument(name = "save universal configurator event", skip(db_pool))]
async fn submit_universal_configurator_event(
Query(event): Query<UniversalConfiguratorEvent>,
State(AppState { db_pool, .. }): State<AppState>,
) -> Response {
if let Err(error) = write_universal_widget_event(&event, &db_pool).await {
tracing::warn!("Error while saving event {}", error);
tracing::warn!("error while saving event {}", error);
};

StatusCode::OK.into_response()
}

#[tracing::instrument(name = "Log widget event", skip(db_pool))]
#[tracing::instrument(name = "log widget event", skip(db_pool))]
async fn log_widget_event(
Query(event): Query<WidgetEvent>,
State(AppState { db_pool, .. }): State<AppState>,
) -> Response {
if let Err(error) = write_widget_event(&event, &db_pool).await {
tracing::warn!("Error while saving event {}", error);
tracing::warn!("error while saving event {}", error);
};

StatusCode::OK.into_response()
Expand Down
5 changes: 5 additions & 0 deletions apps/server/tests/e2e/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub struct TestApp {
pub jwt_secret: Secret<String>,
pub base_url: String,
pub bc_secret: Secret<String>,
pub bc_client_id: String,
pub bc_redirect_uri: String,

pub test_client: Client,
Expand Down Expand Up @@ -67,6 +68,7 @@ pub async fn spawn_app() -> TestApp {
db_pool: get_connection_pool(&configuration.database),
jwt_secret: configuration.application.jwt_secret,
bc_secret: configuration.bigcommerce.client_secret,
bc_client_id: configuration.bigcommerce.client_id,
bc_redirect_uri: configuration.bigcommerce.install_redirect_uri,
base_url: configuration.application.base_url,
test_client: reqwest::Client::new(),
Expand Down Expand Up @@ -119,8 +121,11 @@ impl TestApp {
let expiration = now + Duration::minutes(30);
let claims = serde_json::json!( {
"iss": "bc",
"aud": self.bc_client_id,
"iat": now.unix_timestamp(),
"nbf": now.unix_timestamp() - 5,
"exp": expiration.unix_timestamp(),
"jti": uuid::Uuid::new_v4().to_string(),
"sub": sub,
"user": user,
"owner": owner,
Expand Down