Files
memgraph/src/communication/bolt/v1/states/error.hpp
Matej Ferencevic e28fd2025d Rename bolt::DecodedValue to bolt::Value
Reviewers: teon.banek

Reviewed By: teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1506
2018-07-24 15:59:20 +02:00

83 lines
2.5 KiB
C++

#pragma once
#include <fmt/format.h>
#include <glog/logging.h>
#include "communication/bolt/v1/codes.hpp"
#include "communication/bolt/v1/state.hpp"
#include "communication/bolt/v1/value.hpp"
#include "utils/cast.hpp"
namespace communication::bolt {
/**
* Error state run function
* This function handles a Bolt session when it is in an error state.
* The error state is exited upon receiving an ACK_FAILURE or RESET message.
* @param session the session that should be used for the run
*/
template <typename TSession>
State StateErrorRun(TSession &session, State state) {
Marker marker;
Signature signature;
if (!session.decoder_.ReadMessageHeader(&signature, &marker)) {
DLOG(WARNING) << "Missing header data!";
return State::Close;
}
// Clear the data buffer if it has any leftover data.
session.encoder_buffer_.Clear();
if (signature == Signature::AckFailure || signature == Signature::Reset) {
if (signature == Signature::AckFailure) {
DLOG(INFO) << "AckFailure received";
} else {
DLOG(INFO) << "Reset received";
}
if (!session.encoder_.MessageSuccess()) {
DLOG(WARNING) << "Couldn't send success message!";
return State::Close;
}
if (signature == Signature::Reset) {
session.Abort();
return State::Idle;
}
// We got AckFailure get back to right state.
CHECK(state == State::Error) << "Shouldn't happen";
return State::Idle;
} else {
uint8_t value = utils::UnderlyingCast(marker);
// All bolt client messages have less than 15 parameters so if we receive
// anything than a TinyStruct it's an error.
if ((value & 0xF0) != utils::UnderlyingCast(Marker::TinyStruct)) {
DLOG(WARNING) << fmt::format(
"Expected TinyStruct marker, but received 0x{:02X}!", value);
return State::Close;
}
// We need to clean up all parameters from this command.
value &= 0x0F; // The length is stored in the lower nibble.
Value dv;
for (int i = 0; i < value; ++i) {
if (!session.decoder_.ReadValue(&dv)) {
DLOG(WARNING) << fmt::format("Couldn't clean up parameter {} / {}!", i,
value);
return State::Close;
}
}
// Ignore this message.
if (!session.encoder_.MessageIgnored()) {
DLOG(WARNING) << "Couldn't send ignored message!";
return State::Close;
}
// Cleanup done, command ignored, stay in error state.
return state;
}
}
} // namespace communication::bolt