Skip to content

Commit 46b6a22

Browse files
authored
Refactor/error improvements (#15)
* refactor: move errors to its own module * refactor: remove panic call from start API * refactor: remove ServiceBuilder default implementation * refactor: use new output format for error (initial changes) * feat: add new HTTP example with protobuf * feat: add new service error structure - Adding new error structure to be used by applications as their errors. * feat: improve public error API * chore: update example * feat: add support for hiding response error fields - Also adding option to log every error returned by a service. * refactor: code style adjustments * test: add tests for service error object * chore: update coverage badge
1 parent 9f47c17 commit 46b6a22

File tree

38 files changed

+2009
-197
lines changed

38 files changed

+2009
-197
lines changed

docs/mikros.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,15 @@ max_diff_range = 100
187187
Mikros has some environment variables that it uses to set custom information
188188
while the application is running. They are the following:
189189

190-
| Name | Description |
191-
|----------------------------|--------------------------------------------------------------------------------------------------------------------------|
192-
| MIKROS_SERVICE_DEPLOY | A string to set the current deployment server of the application, like (dev, stage, prod). Default: local |
193-
| MIKROS_TRACKER_HEADER_NAME | A header name where the track ID will be located in HTTP requests/responses (not implemented yet). Default: X-Request-ID |
194-
| MIKROS_COUPLED_NAMESPACE | The namespace where services/applications are running, to build the gRPC connection URL. Default: localhost |
195-
| MIKROS_COUPLED_PORT | The default port for dependent gRPC services. Default: 7070 |
196-
| MIKROS_GRPC_PORT | Default listening port for gRPC applications. Default: 7070 |
197-
| MIKROS_HTTP_PORT | Default listening port for HTTP applications. Default: 8080 |
190+
| Name | Description |
191+
|-----------------------------|--------------------------------------------------------------------------------------------------------------------------|
192+
| MIKROS_SERVICE_DEPLOY | A string to set the current deployment server of the application, like (dev, stage, prod). Default: local |
193+
| MIKROS_TRACKER_HEADER_NAME | A header name where the track ID will be located in HTTP requests/responses (not implemented yet). Default: X-Request-ID |
194+
| MIKROS_COUPLED_NAMESPACE | The namespace where services/applications are running, to build the gRPC connection URL. Default: localhost |
195+
| MIKROS_COUPLED_PORT | The default port for dependent gRPC services. Default: 7070 |
196+
| MIKROS_GRPC_PORT | Default listening port for gRPC applications. Default: 7070 |
197+
| MIKROS_HTTP_PORT | Default listening port for HTTP applications. Default: 8080 |
198+
| MIKROS_HIDE_RESPONSE_FIELDS | A comma separated list of fields to be hidden in HTTP services error response. |
198199

199200
### The service structure
200201

examples/apps/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ members = [
66
"grpc_with_lifecycle",
77
"http",
88
"http_with_lifecycle",
9-
"http_with_lifecycle_and_state",
9+
"http_with_lifecycle_and_state", "http_with_protobuf",
1010
"http_with_state",
1111
"native",
1212
"script"

examples/apps/cronjob_service/service.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "cronjob-example"
22
version = "v0.1.0"
33
language = "rust"
44
product = "examples"
5-
types = ["cronjob"]
5+
types = ["cronjob2"]
66

77
[features.simple_api]
88
enabled = true

examples/apps/cronjob_service/src/main.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,14 @@ impl cronjob::CronjobService for Service {
1919
}
2020

2121
#[tokio::main]
22-
async fn main() {
22+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
2323
let s = Box::new(Service::default());
2424
let c = Box::new(CronjobBuilder::new(s).build());
2525

26-
let svc = ServiceBuilder::default()
26+
let mut svc = ServiceBuilder::new()
2727
.custom(c)
2828
.with_features(vec![simple_api::new(), example::new()])
29-
.build();
29+
.build()?;
3030

31-
match svc {
32-
Ok(mut svc) => svc.start().await,
33-
Err(e) => panic!("{}", e.to_string()),
34-
}
31+
Ok(svc.start().await?)
3532
}

examples/apps/grpc/src/main.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
5858
let greeter = Arc::new(MyGreeter::new(ctx.clone()));
5959
let greeter_service = GreeterServer::from_arc(greeter);
6060

61-
let svc = ServiceBuilder::default().grpc(greeter_service).build();
61+
let mut svc = ServiceBuilder::new()
62+
.grpc(greeter_service)
63+
.build()?;
6264

63-
match svc {
64-
Ok(mut svc) => svc.start().await,
65-
Err(e) => panic!("{}", e.to_string()),
66-
}
67-
68-
Ok(())
65+
Ok(svc.start().await?)
6966
}

examples/apps/grpc_with_lifecycle/src/main.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
8787
let greeter = Arc::new(MyGreeter::new(ctx.clone()));
8888
let greeter_service = GreeterServer::from_arc(greeter);
8989

90-
let svc = ServiceBuilder::default()
90+
let mut svc = ServiceBuilder::new()
9191
.grpc_with_lifecycle(greeter_service, ctx.clone())
92-
.build();
92+
.build()?;
9393

94-
match svc {
95-
Ok(mut svc) => svc.start().await,
96-
Err(e) => panic!("{}", e.to_string()),
97-
}
98-
99-
Ok(())
94+
Ok(svc.start().await?)
10095
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "http_with_protobuf"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
chrono = "0.4.39"
8+
example = { path = "../../features/example" }
9+
mikros = { path = "../../../" }
10+
prost = "0.13.3"
11+
prost-wkt = "0.6.0"
12+
prost-wkt-types = "0.6.0"
13+
serde = "1.0.215"
14+
tokio = { version = "1.41.1", features = ["full"] }
15+
tonic = "0.12.3"
16+
uuid = {version = "1.11.0", features = ["serde", "v4"]}
17+
18+
[build-dependencies]
19+
tonic-build = "0.12.3"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
fn main() {
2+
tonic_build::configure()
3+
.protoc_arg("--mikros-extensions_out=src")
4+
.protoc_arg("--mikros-extensions_opt=settings=protoc-gen-mikros-extensions.toml")
5+
.out_dir("src/generated")
6+
.extern_path(
7+
".google.protobuf.Timestamp",
8+
"::prost_wkt_types::Timestamp"
9+
)
10+
.compile_protos(
11+
&["proto/card.proto"],
12+
&["proto", "plugin"],
13+
)
14+
.unwrap_or_else(|e| panic!("Failed to compile protos: {:?}", e));
15+
16+
// Set files that trigger this build process if changed.
17+
println!("cargo:rerun-if-changed=proto/card.proto");
18+
println!("cargo:rerun-if-changed=protoc-gen-mikros-extensions.toml");
19+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
syntax = "proto3";
2+
3+
package card;
4+
5+
option go_package = "examples/gen/go/services/card;card";
6+
7+
import "google/api/annotations.proto";
8+
import "google/protobuf/timestamp.proto";
9+
import "mikros/extensions/extensions.proto";
10+
11+
enum CardType {
12+
CARD_TYPE_UNSPECIFIED = 0;
13+
CARD_TYPE_CREDIT = 1;
14+
CARD_TYPE_DEBIT = 2;
15+
}
16+
17+
// The service entity
18+
message CardWire {
19+
string id = 1;
20+
string owner_name = 2;
21+
string card_id = 3;
22+
google.protobuf.Timestamp created_at = 4;
23+
google.protobuf.Timestamp updated_at = 5;
24+
}
25+
26+
// The service definition
27+
service CardService {
28+
rpc CreateCard(CreateCardRequest) returns (CreateCardResponse) {
29+
option (google.api.http) = {
30+
post: "/card/v1/cards"
31+
body: "*"
32+
};
33+
34+
option (mikros.extensions.method_options) = {
35+
http: {
36+
header: "debug"
37+
}
38+
};
39+
}
40+
41+
rpc GetCard(GetCardRequest) returns (GetCardResponse) {
42+
option (google.api.http) = {
43+
get: "/card/v1/cards/{id}"
44+
};
45+
46+
option (mikros.extensions.method_options) = {
47+
http: {
48+
header: "debug"
49+
}
50+
};
51+
}
52+
53+
rpc UpdateCard(UpdateCardRequest) returns (UpdateCardResponse) {
54+
option (google.api.http) = {
55+
put: "/card/v1/cards/{id}"
56+
body: "*"
57+
};
58+
59+
option (mikros.extensions.method_options) = {
60+
http: {
61+
header: "debug"
62+
}
63+
};
64+
}
65+
66+
rpc DeleteCard(DeleteCardRequest) returns (DeleteCardResponse) {
67+
option (google.api.http) = {
68+
delete: "/card/v1/cards/{id}"
69+
};
70+
71+
option (mikros.extensions.method_options) = {
72+
http: {
73+
header: "debug"
74+
}
75+
};
76+
}
77+
}
78+
79+
message CreateCardRequest {
80+
string owner_name = 1;
81+
string card_id = 2;
82+
bool debug = 3;
83+
}
84+
85+
message CreateCardResponse {
86+
CardWire card = 1;
87+
}
88+
89+
message GetCardRequest {
90+
string id = 1;
91+
bool debug = 2;
92+
}
93+
94+
message GetCardResponse {
95+
CardWire card = 1;
96+
}
97+
98+
message UpdateCardRequest {
99+
string id = 1;
100+
string owner_name = 2;
101+
string card_id = 3;
102+
bool debug = 4;
103+
}
104+
105+
message UpdateCardResponse {
106+
CardWire card = 1;
107+
}
108+
109+
message DeleteCardRequest {
110+
string id = 1;
111+
bool debug = 2;
112+
}
113+
114+
message DeleteCardResponse {
115+
CardWire card = 1;
116+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
debug = true
2+
3+
[suffix]
4+
domain = "Domain"
5+
outbound = "Outbound"
6+
wire = "Wire"
7+
wire_input = "Request"
8+
wire_output = "Response"
9+
10+
[templates.rust]
11+
enabled = true
12+
single_module = true
13+
module_name = "api"
14+
run_rustfmt = true
15+
fmt_edition = "2021"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name = "http-proto-example"
2+
version = "v0.1.0"
3+
language = "rust"
4+
product = "examples"
5+
types = ["http"]
6+
7+
[features.example]
8+
enabled = true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod router;
2+

0 commit comments

Comments
 (0)