Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 0.50.0 - TBD

### Enhancements
- Added logic to set `code` when upgrading version 1 `ErrorMsg` to newer versions

## 0.49.0 - 2026-02-24

### Enhancements
Expand Down
21 changes: 21 additions & 0 deletions src/v1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,27 @@ v2::ErrorMsg ErrorMsg::ToV2() const {
ErrorCode::Unset,
std::numeric_limits<std::uint8_t>::max()};
std::copy(err.begin(), err.end(), ret.err.begin());
const auto null_it = std::find(err.begin(), err.end(), '\0');
if (null_it != err.end()) {
constexpr auto kApiKeyDeactivated = "User or API key deactivated";
constexpr auto kConnectionLimit = "User has reached their open connection limit";
constexpr auto kSymbolResolution = "Failed to resolve symbol";
constexpr auto kInternalError = "Internal error";
constexpr auto kSlowClient = "Slow client detected for ";

if (std::strcmp(Err(), kApiKeyDeactivated) == 0) {
ret.code = ErrorCode::ApiKeyDeactivated;
} else if (std::strcmp(Err(), kConnectionLimit) == 0) {
ret.code = ErrorCode::ConnectionLimitExceeded;
} else if (std::strncmp(Err(), kSymbolResolution, std::strlen(kSymbolResolution)) ==
0) {
ret.code = ErrorCode::SymbolResolutionFailed;
} else if (std::strcmp(Err(), kInternalError) == 0) {
ret.code = ErrorCode::InternalError;
} else if (std::strncmp(Err(), kSlowClient, std::strlen(kSlowClient)) == 0) {
ret.code = ErrorCode::SkippedRecordsAfterSlowReading;
}
}
return ret;
}

Expand Down
28 changes: 28 additions & 0 deletions tests/src/v1_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,32 @@ TEST(V1Tests, TestSystemMsgCodeUpgrade) {
const auto res5 = target.ToV2();
EXPECT_EQ(res5.code, SystemCode::ReplayCompleted);
}

TEST(V1Tests, TestErrorMsgCodeUpgrade) {
v1::ErrorMsg target{RecordHeader{
sizeof(v1::ErrorMsg) / RecordHeader::kLengthMultiplier, RType::Error, 0, 0, {}}};
std::strcpy(target.err.data(), "User or API key deactivated");
const auto res1 = target.ToV2();
EXPECT_EQ(res1.code, ErrorCode::ApiKeyDeactivated);

target.err = {};
std::strcpy(target.err.data(), "User has reached their open connection limit");
const auto res2 = target.ToV2();
EXPECT_EQ(res2.code, ErrorCode::ConnectionLimitExceeded);

target.err = {};
std::strcpy(target.err.data(), "Failed to resolve symbol: AAPL");
const auto res3 = target.ToV2();
EXPECT_EQ(res3.code, ErrorCode::SymbolResolutionFailed);

target.err = {};
std::strcpy(target.err.data(), "Internal error");
const auto res4 = target.ToV2();
EXPECT_EQ(res4.code, ErrorCode::InternalError);

target.err = {};
std::strcpy(target.err.data(), "Slow client detected for mbo. Skipped records");
const auto res5 = target.ToV2();
EXPECT_EQ(res5.code, ErrorCode::SkippedRecordsAfterSlowReading);
}
} // namespace databento::v1::tests
Loading