Skip to content

Commit 49030d4

Browse files
authored
Merge branch 'main' into nathan/more-ui-tests
2 parents 19e33b2 + 72d8de0 commit 49030d4

14 files changed

Lines changed: 113 additions & 4 deletions

Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ members = [
55
"src/backend/impl",
66
"src/backend/external_canisters",
77
"src/backend/logs",
8+
"src/backend/macros",
89
]
910

1011
[profile.release]

src/backend/impl/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ dev = []
1111

1212
[dependencies]
1313
backend_api = { path = "../api" }
14+
backend_macros = { path = "../macros" }
1415
external_canisters = { path = "../external_canisters" }
1516

1617
ic-cdk.workspace = true

src/backend/impl/src/controllers/proposal_controller.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ use crate::{
88
use backend_api::{
99
ApiError, ApiResult, ListProposalsRequest, ListProposalsResponse, SyncProposalsResponse,
1010
};
11+
use backend_macros::log_errors;
1112
use candid::Principal;
1213
use ic_cdk::*;
1314

1415
#[update]
16+
#[log_errors(crate::services::log_update_call_error)]
1517
async fn sync_proposals() -> ApiResult<SyncProposalsResponse> {
1618
let calling_principal = caller();
1719

src/backend/impl/src/controllers/proposal_review_commit_controller.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use backend_api::{
22
ApiError, ApiResult, CreateProposalReviewCommitRequest, CreateProposalReviewCommitResponse,
33
DeleteProposalReviewCommitRequest, UpdateProposalReviewCommitRequest,
44
};
5+
use backend_macros::log_errors;
56
use candid::Principal;
67
use ic_cdk::*;
78

@@ -17,6 +18,7 @@ use crate::{
1718
};
1819

1920
#[update]
21+
#[log_errors(crate::services::log_update_call_error)]
2022
async fn create_proposal_review_commit(
2123
request: CreateProposalReviewCommitRequest,
2224
) -> ApiResult<CreateProposalReviewCommitResponse> {
@@ -29,6 +31,7 @@ async fn create_proposal_review_commit(
2931
}
3032

3133
#[update]
34+
#[log_errors(crate::services::log_update_call_error)]
3235
async fn update_proposal_review_commit(
3336
request: UpdateProposalReviewCommitRequest,
3437
) -> ApiResult<()> {
@@ -40,6 +43,7 @@ async fn update_proposal_review_commit(
4043
}
4144

4245
#[update]
46+
#[log_errors(crate::services::log_update_call_error)]
4347
async fn delete_proposal_review_commit(
4448
request: DeleteProposalReviewCommitRequest,
4549
) -> ApiResult<()> {

src/backend/impl/src/controllers/proposal_review_controller.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ use backend_api::{
1616
GetMyProposalReviewSummaryResponse, GetProposalReviewRequest, GetProposalReviewResponse,
1717
ListProposalReviewsRequest, ListProposalReviewsResponse, UpdateProposalReviewRequest,
1818
};
19+
use backend_macros::log_errors;
1920
use candid::Principal;
2021
use ic_cdk::*;
2122

2223
#[update]
24+
#[log_errors(crate::services::log_update_call_error)]
2325
async fn create_proposal_review(
2426
request: CreateProposalReviewRequest,
2527
) -> ApiResult<CreateProposalReviewResponse> {
@@ -32,6 +34,7 @@ async fn create_proposal_review(
3234
}
3335

3436
#[update]
37+
#[log_errors(crate::services::log_update_call_error)]
3538
fn update_proposal_review(request: UpdateProposalReviewRequest) -> ApiResult<()> {
3639
let calling_principal = caller();
3740

@@ -61,6 +64,7 @@ fn get_proposal_review(request: GetProposalReviewRequest) -> ApiResult<GetPropos
6164
}
6265

6366
#[update]
67+
#[log_errors(crate::services::log_update_call_error)]
6468
async fn create_proposal_review_image(
6569
request: CreateProposalReviewImageRequest,
6670
) -> ApiResult<CreateProposalReviewImageResponse> {
@@ -73,6 +77,7 @@ async fn create_proposal_review_image(
7377
}
7478

7579
#[update]
80+
#[log_errors(crate::services::log_update_call_error)]
7681
fn delete_proposal_review_image(request: DeleteProposalReviewImageRequest) -> ApiResult<()> {
7782
let calling_principal = caller();
7883

src/backend/impl/src/controllers/user_profile_controller.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use backend_api::{
99
GetMyUserProfileResponse, ListReviewerProfilesResponse, UpdateMyUserProfileRequest,
1010
UpdateUserProfileRequest,
1111
};
12+
use backend_macros::log_errors;
1213
use candid::Principal;
1314
use ic_cdk::*;
1415

@@ -38,6 +39,7 @@ fn get_my_user_profile_history() -> ApiResult<GetMyUserProfileHistoryResponse> {
3839
}
3940

4041
#[update]
42+
#[log_errors(crate::services::log_update_call_error)]
4143
async fn create_my_user_profile() -> ApiResult<CreateMyUserProfileResponse> {
4244
let calling_principal = caller();
4345

@@ -48,6 +50,7 @@ async fn create_my_user_profile() -> ApiResult<CreateMyUserProfileResponse> {
4850
}
4951

5052
#[update]
53+
#[log_errors(crate::services::log_update_call_error)]
5154
fn update_my_user_profile(request: UpdateMyUserProfileRequest) -> ApiResult<()> {
5255
let calling_principal = caller();
5356

@@ -57,6 +60,7 @@ fn update_my_user_profile(request: UpdateMyUserProfileRequest) -> ApiResult<()>
5760
}
5861

5962
#[update]
63+
#[log_errors(crate::services::log_update_call_error)]
6064
async fn update_user_profile(request: UpdateUserProfileRequest) -> ApiResult<()> {
6165
let calling_principal = caller();
6266

src/backend/impl/src/services/log_service.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,24 @@ impl<T: LogRepository> LogServiceImpl<T> {
8585
}
8686
}
8787

88+
/// Mainly used with the `log_errors` macro.
89+
///
90+
/// # Example
91+
/// ```
92+
/// use ic_cdk::update;
93+
/// use backend_macros::log_errors;
94+
///
95+
/// #[update]
96+
/// #[log_errors(crate::services::log_update_call_error)]
97+
/// async fn create_proposal_review() -> ApiResult<()> {
98+
/// Ok(())
99+
/// }
100+
/// ```
101+
pub fn log_update_call_error(message: String, context: String) {
102+
// We can ignore this error
103+
let _ = LogServiceImpl::default().log_error(message, Some(context));
104+
}
105+
88106
#[cfg(test)]
89107
mod tests {
90108
use super::*;

src/backend/macros/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "backend_macros"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
proc-macro = true
8+
9+
[dependencies]
10+
backend_api = { path = "../api" }
11+
12+
syn = "2.0"
13+
quote = "1.0"

src/backend/macros/src/lib.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
extern crate proc_macro;
2+
use proc_macro::TokenStream;
3+
use quote::quote;
4+
use syn::{parse_macro_input, ItemFn, Path, ReturnType};
5+
6+
#[proc_macro_attribute]
7+
pub fn log_errors(attr: TokenStream, item: TokenStream) -> TokenStream {
8+
let log_fn = parse_macro_input!(attr as Path);
9+
10+
let input = parse_macro_input!(item as ItemFn);
11+
let fn_name = &input.sig.ident;
12+
let fn_args = &input.sig.inputs;
13+
let fn_return_type = &input.sig.output;
14+
let fn_block = &input.block;
15+
let fn_async = &input.sig.asyncness;
16+
17+
// Ensure the function returns a Result
18+
let result = match fn_return_type {
19+
ReturnType::Type(_, _) => {
20+
let block = if fn_async.is_some() {
21+
quote! { (async { #fn_block }).await }
22+
} else {
23+
quote! { (|| #fn_block)() }
24+
};
25+
26+
quote! {
27+
#fn_async fn #fn_name(#fn_args) #fn_return_type {
28+
let result = #block;
29+
if let backend_api::ApiResult::Err(ref e) = result {
30+
let message = e.to_string();
31+
let context = stringify!(#fn_name);
32+
#log_fn(message, context.to_string());
33+
}
34+
result
35+
}
36+
}
37+
}
38+
_ => quote! {
39+
compile_error!("The log_errors macro can only be applied to functions that return a Result.");
40+
},
41+
};
42+
43+
result.into()
44+
}

0 commit comments

Comments
 (0)