Skip to content

Commit

Permalink
feat: derive error codes using the ErrorCode trait
Browse files Browse the repository at this point in the history
  • Loading branch information
carneiro-cw committed Jan 6, 2025
1 parent c45bed8 commit 7246dd6
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 29 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ quick_cache = "=0.6.9"
sugars = "=3.0.1"
thiserror = "=1.0.61"
uuid = { version = "=1.10.0", features = ["v7"]}
stratus_macros = { path = "./crates/stratus_macros" }

# async
tokio = { version = "=1.38.0", features = [
Expand Down
12 changes: 10 additions & 2 deletions crates/stratus_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput, Data, Fields, Meta, Expr, ExprLit, Lit};
use syn::parse_macro_input;
use syn::Data;
use syn::DeriveInput;
use syn::Expr;
use syn::ExprLit;
use syn::Fields;
use syn::Lit;
use syn::Meta;

#[proc_macro_derive(ErrorCode, attributes(error_code))]
pub fn derive_error_code(input: TokenStream) -> TokenStream {
Expand Down Expand Up @@ -87,10 +94,11 @@ fn derive_error_code_impl(input: DeriveInput) -> proc_macro2::TokenStream {

#[cfg(test)]
mod tests {
use crate::derive_error_code_impl;
use proc_macro2::TokenStream;
use quote::quote;

use crate::derive_error_code_impl;

#[test]
fn test_derive_error_code() {
let input = TokenStream::from(quote! {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe("Leader & Follower change integration test", function () {
"2s",
"100ms",
]);
expect(response.data.error.code).to.equal(-32009);
expect(response.data.error.code).to.equal(7007);
expect(response.data.error.message).to.equal("Can't change miner mode while transactions are enabled.");
});

Expand All @@ -62,7 +62,7 @@ describe("Leader & Follower change integration test", function () {
"2s",
"100ms",
]);
expect(response.data.error.code).to.equal(-32603);
expect(response.data.error.code).to.equal(6002);
expect(response.data.error.message.split("\n")[0]).to.equal(
"Unexpected error: can't change miner mode from Interval without pausing it first",
);
Expand Down Expand Up @@ -103,7 +103,7 @@ describe("Leader & Follower change integration test", function () {
it("Change Follower to Leader with transactions enabled should fail", async function () {
updateProviderUrl("stratus-follower");
const response = await sendAndGetFullResponse("stratus_changeToLeader", []);
expect(response.data.error.code).to.equal(-32009);
expect(response.data.error.code).to.equal(7007);
expect(response.data.error.message).to.equal("Can't change miner mode while transactions are enabled.");
});

Expand Down Expand Up @@ -196,7 +196,7 @@ describe("Leader & Follower change integration test", function () {
let successCount = 0;
let semaphoreFailureCount = 0;

const SEMAPHORE_ERROR_CODE = -32009;
const SEMAPHORE_ERROR_CODE = 7005;
const SEMAPHORE_ERROR_MESSAGE = "Stratus node is already in the process of changing mode.";

allResponses.forEach((response, index) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ it("Test follower health is based on getting new blocks", async function () {
await new Promise((resolve) => setTimeout(resolve, 5000));

const unhealthyResponse = await sendAndGetFullResponse("stratus_health", []);
expect(unhealthyResponse.data.error.code).to.equal(-32009);
expect(unhealthyResponse.data.error.code).to.equal(7001);
expect(unhealthyResponse.data.error.message).to.equal("Stratus is not ready to start servicing requests.");

// Start the leader again
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe("Leader & Follower importer integration test", function () {
it("Shutdown command to Leader should fail", async function () {
updateProviderUrl("stratus");
const responseLeader = await sendAndGetFullResponse("stratus_shutdownImporter", []);
expect(responseLeader.data.error.code).eq(-32009);
expect(responseLeader.data.error.code).eq(7003);
expect(responseLeader.data.error.message).eq("Stratus node is not a follower.");
});

Expand All @@ -46,7 +46,7 @@ describe("Leader & Follower importer integration test", function () {
it("Shutdown command to Follower when Importer is already shutdown should fail", async function () {
updateProviderUrl("stratus-follower");
const responseFollower = await sendAndGetFullResponse("stratus_shutdownImporter", []);
expect(responseFollower.data.error.code).to.equal(-32603);
expect(responseFollower.data.error.code).to.equal(4002);
expect(responseFollower.data.error.message).to.equal("Importer is already shutdown.");
});

Expand All @@ -56,7 +56,7 @@ describe("Leader & Follower importer integration test", function () {
expect(followerNode.is_leader).to.equal(false);
expect(followerNode.is_importer_shutdown).to.equal(true);
const followerHealth = await sendAndGetFullResponse("stratus_health", []);
expect(followerHealth.data.error.code).eq(-32009);
expect(followerHealth.data.error.code).eq(7001);
expect(followerHealth.data.error.message).eq("Stratus is not ready to start servicing requests.");
});

Expand Down Expand Up @@ -97,7 +97,7 @@ describe("Leader & Follower importer integration test", function () {
const nonce = parseInt(nonceResponse.data.result, 16);
const signedTx = await BOB.signWeiTransfer(ALICE.address, 1, nonce);
const txResponse = await sendAndGetFullResponse("eth_sendRawTransaction", [signedTx]);
expect(txResponse.data.error.code).to.equal(-32603);
expect(txResponse.data.error.code).to.equal(5001);
expect(txResponse.data.error.message).to.equal("Consensus is temporarily unavailable for follower node.");
});

Expand All @@ -109,14 +109,14 @@ describe("Leader & Follower importer integration test", function () {
"2s",
"100ms",
]);
expect(responseLeader.data.error.code).to.equal(-32009);
expect(responseLeader.data.error.code).to.equal(7003);
expect(responseLeader.data.error.message).to.equal("Stratus node is not a follower.");
});

it("Init command to Follower without addresses should fail", async function () {
updateProviderUrl("stratus-follower");
const responseInvalidFollower = await sendAndGetFullResponse("stratus_initImporter", []);
expect(responseInvalidFollower.data.error.code).to.equal(-32602);
expect(responseInvalidFollower.data.error.code).to.equal(1005);
expect(responseInvalidFollower.data.error.message).to.equal("Expected String parameter, but received nothing.");
});

Expand All @@ -127,7 +127,7 @@ describe("Leader & Follower importer integration test", function () {
"2s",
"100ms",
]);
expect(responseInvalidAddressFollower.data.error.code).to.equal(-32603);
expect(responseInvalidAddressFollower.data.error.code).to.equal(4004);
expect(responseInvalidAddressFollower.data.error.message).to.equal("Failed to initialize importer.");
});

Expand All @@ -148,7 +148,7 @@ describe("Leader & Follower importer integration test", function () {
"2s",
"100ms",
]);
expect(responseSecondInitFollower.data.error.code).to.equal(-32603);
expect(responseSecondInitFollower.data.error.code).to.equal(4001);
expect(responseSecondInitFollower.data.error.message).to.equal("Importer is already running.");
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ describe("Miner mode change integration test", function () {
it("Miner change to External on Leader should fail because transactions are enabled", async function () {
updateProviderUrl("stratus");
const response = await sendAndGetFullResponse("stratus_changeMinerMode", ["external"]);
expect(response.data.error.code).eq(-32009);
expect(response.data.error.code).eq(7007);
expect(response.data.error.message).eq("Can't change miner mode while transactions are enabled.");
});

it("Miner change to Interval on Follower should fail because transactions are enabled", async function () {
updateProviderUrl("stratus-follower");
const response = await sendAndGetFullResponse("stratus_changeMinerMode", ["1s"]);
expect(response.data.error.code).eq(-32009);
expect(response.data.error.code).eq(7007);
expect(response.data.error.message).eq("Can't change miner mode while transactions are enabled.");
});

Expand All @@ -65,7 +65,7 @@ describe("Miner mode change integration test", function () {
it("Miner change to External on Leader should fail because miner is enabled", async function () {
updateProviderUrl("stratus");
const response = await sendAndGetFullResponse("stratus_changeMinerMode", ["external"]);
expect(response.data.error.code).eq(-32603);
expect(response.data.error.code).eq(6002);
expect(response.data.error.message.split("\n")[0]).to.equal(
"Unexpected error: can't change miner mode from Interval without pausing it first",
);
Expand All @@ -74,7 +74,7 @@ describe("Miner mode change integration test", function () {
it("Miner change to Interval on Follower should fail because importer wasn't stopped", async function () {
updateProviderUrl("stratus-follower");
const response = await sendAndGetFullResponse("stratus_changeMinerMode", ["1s"]);
expect(response.data.error.code).eq(-32603);
expect(response.data.error.code).eq(6002);
expect(response.data.error.message).eq("Consensus is set.");
});

Expand All @@ -97,14 +97,14 @@ describe("Miner mode change integration test", function () {
it("Miner change on Leader without params should fail", async function () {
updateProviderUrl("stratus");
const response = await sendAndGetFullResponse("stratus_changeMinerMode", []);
expect(response.data.error.code).eq(-32602);
expect(response.data.error.code).eq(1005);
expect(response.data.error.message).eq("Expected String parameter, but received nothing.");
});

it("Miner change on Leader with invalid params should fail", async function () {
updateProviderUrl("stratus");
const response = await sendAndGetFullResponse("stratus_changeMinerMode", ["invalidMode"]);
expect(response.data.error.code).eq(-32602);
expect(response.data.error.code).eq(1009);
expect(response.data.error.message).eq("Miner mode param is invalid.");
});

Expand All @@ -123,7 +123,7 @@ describe("Miner mode change integration test", function () {
it("Miner change on Leader to Automine should fail because it is not supported", async function () {
updateProviderUrl("stratus");
const response = await sendAndGetFullResponse("stratus_changeMinerMode", ["automine"]);
expect(response.data.error.code).eq(-32603);
expect(response.data.error.code).eq(6002);
expect(response.data.error.message.split("\n")[0]).eq(
"Unexpected error: Miner mode change to 'automine' is unsupported.",
);
Expand Down Expand Up @@ -167,7 +167,7 @@ describe("Miner mode change integration test", function () {

// Change Miner mode to External on Leader with Pending Transactions should fail
const changeMinerModeResponse = await sendAndGetFullResponse("stratus_changeMinerMode", ["external"]);
expect(changeMinerModeResponse.data.error.code).eq(-32603);
expect(changeMinerModeResponse.data.error.code).eq(6002);
expect(changeMinerModeResponse.data.error.message).eq("There are (1) pending transactions.");

// Clean up
Expand Down
4 changes: 2 additions & 2 deletions e2e/test/admin/e2e-admin-password-enabled.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ describe("Admin Password (with password set)", () => {

it("should reject requests without password", async () => {
const error = await sendAndGetError("stratus_enableTransactions", []);
expect(error.code).eq(-32009); // Internal error
expect(error.code).eq(7004); // Internal error
expect(error.message).to.contain("Incorrect password");
});

it("should reject requests with wrong password", async () => {
const headers = { Authorization: "Password wrong123" };
const error = await sendAndGetError("stratus_enableTransactions", [], headers);
expect(error.code).eq(-32009); // Internal error
expect(error.code).eq(7004); // Internal error
expect(error.message).to.contain("Incorrect password");
});

Expand Down
4 changes: 2 additions & 2 deletions e2e/test/automine/e2e-json-rpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ describe("JSON-RPC", () => {
it("fails on HTTP", async () => {
const error = await sendAndGetError("eth_subscribe", ["newHeads"]);
expect(error).to.not.be.null;
expect(error.code).eq(-32603); // Internal error
expect(error.code).eq(6002); // Internal error
});
it("subscribes to newHeads receives success subscription event", async () => {
const waitTimeInMilliseconds = 40;
Expand Down Expand Up @@ -359,7 +359,7 @@ describe("JSON-RPC", () => {
expect(response.error).to.not.be.undefined;
expect(response.error.code).to.not.be.undefined;
expect(response.error.code).to.be.a("number");
expect(response.error.code).eq(-32602);
expect(response.error.code).eq(1006);
});

it("validates newHeads event", async () => {
Expand Down
4 changes: 2 additions & 2 deletions e2e/test/external/e2e-json-rpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ describe("JSON-RPC", () => {
it("fails on HTTP", async () => {
const error = await sendAndGetError("eth_subscribe", ["newHeads"]);
expect(error).to.not.be.null;
expect(error.code).eq(-32603); // Internal error
expect(error.code).eq(6002); // Internal error
});
it("subscribes to newHeads receives success subscription event", async () => {
const waitTimeInMilliseconds = 40;
Expand Down Expand Up @@ -517,7 +517,7 @@ describe("JSON-RPC", () => {
expect(response.error).to.not.be.undefined;
expect(response.error.code).to.not.be.undefined;
expect(response.error.code).to.be.a("number");
expect(response.error.code).eq(-32602);
expect(response.error.code).eq(1006);
});

it("validates newHeads event", async () => {
Expand Down

0 comments on commit 7246dd6

Please sign in to comment.