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

Handle unknown protocol errors gracefully in the sync client #6885

Merged
merged 4 commits into from
Aug 11, 2023

Conversation

jbreams
Copy link
Contributor

@jbreams jbreams commented Aug 11, 2023

What, How & Why?

This makes it so if the server sends a json error message with an action, the sync client won't crash if it doesn't know about the error code sent. This way we don't need to bump the protocol version every time we add an error code.

For legacy ERROR messages - which are still sent by the C++ test server, we ignore the action value.

There's also a new integration test that gets baas to send us a json error message with various unknown errors to validate that the error handling works as expected.

☑️ ToDos

  • 📝 Changelog update
  • 🚦 Tests (or not relevant)
  • C-API, if public C++ API changed.

@jbreams jbreams marked this pull request as ready for review August 11, 2023 19:13
@jbreams jbreams requested review from kmorkos and michael-wb August 11, 2023 19:15
@@ -259,6 +260,7 @@ typedef enum realm_sync_errno_session {
RLM_SYNC_ERR_SESSION_MIGRATE_TO_FLX = 232,
RLM_SYNC_ERR_SESSION_BAD_PROGRESS = 233,
RLM_SYNC_ERR_SESSION_REVERT_TO_PBS = 234,
// Error code 299 is reserved as an "unknown session error" in tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming you let the server team know about these two reserved values?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, I coordinated with @kmorkos about this.

@@ -488,7 +490,7 @@ class ClientProtocol {
if (auto action_it = mapping.find(action_string); action_it != mapping.end()) {
return action_it->second;
}
return action::ApplicationBug;
return action::NoAction;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we should treat any new actions sent by the server that the client doesn't recognize as NoAction?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, going back to the scope, we do call out that it should be ApplicationBug. I'll change this back to the way it was and adjust the tests.

{"action", "ApplicationBug"},
};
nlohmann::json test_command = {{"command", "ECHO_ERROR"},
{"args", nlohmann::json{{"errorCode", 299}, {"errorBody", error_body}}}};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe create a REALM_SYNC_ERR_... constant for error code 199/299?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then they wouldn't be unknown though? I'm comfortable with just commenting on them as being reserved values. We definitely don't need to expose these error codes that will never be used via the C API, IMO.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Then they wouldn't be unknown though?" 😂
I agree with your response

.get();
REQUIRE(test_cmd_res == "{}");
auto error = wait_for_future(std::move(error_future)).get();
REQUIRE(error.status == ErrorCodes::UnknownError);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add one more check to verify the message value from the JSON error is passed through to the status object:

REQUIRE(error.status.reason() == "fake error");

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -279,6 +280,105 @@ static auto make_client_reset_handler()
return std::make_pair(std::move(reset_future), std::move(fn));
}


TEST_CASE("app: error handling integration test", "[sync][flx][baas]") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a new section with an unrecognized "action" value to verify the NoAction response.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor

@kmorkos kmorkos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

Copy link
Contributor

@michael-wb michael-wb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, once the tests have passed.

{"action", "ApplicationBug"},
};
nlohmann::json test_command = {{"command", "ECHO_ERROR"},
{"args", nlohmann::json{{"errorCode", 299}, {"errorBody", error_body}}}};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Then they wouldn't be unknown though?" 😂
I agree with your response

@jbreams jbreams merged commit 30b7a29 into master Aug 11, 2023
@jbreams jbreams deleted the jbr/handle_unknown_errors_gracefully branch August 11, 2023 21:27
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 21, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
3 participants