Skip to content

Commit

Permalink
Fix the error of dropping the HwProblems flag when receiving E_IO_SIL…
Browse files Browse the repository at this point in the history
…ENT (#2939)

* Fix the error of dropping the HwProblems flag when receiving E_IO_SILENT

* Test
  • Loading branch information
drbasic authored Jan 30, 2025
1 parent 87ee61b commit 0ab2620
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 14 deletions.
61 changes: 61 additions & 0 deletions cloud/blockstore/libs/client/session_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1757,6 +1757,67 @@ Y_UNIT_TEST_SUITE(TSessionTest)
// Unfreeze request handlers
promise.SetValue();
}

Y_UNIT_TEST(ShouldPassErrorFlags)
{
auto client = std::make_shared<TTestService>();

size_t sessionNum = 0;
client->MountVolumeHandler =
[&](std::shared_ptr<NProto::TMountVolumeRequest> request)
{
NProto::TMountVolumeResponse response;
response.SetSessionId(ToString(++sessionNum));

auto& volume = *response.MutableVolume();
volume.SetDiskId(request->GetDiskId());
volume.SetBlockSize(4 * 1024);
volume.SetBlocksCount(1024);

return MakeFuture(response);
};

client->UnmountVolumeHandler =
[](std::shared_ptr<NProto::TUnmountVolumeRequest> request)
{
Y_UNUSED(request);
return MakeFuture<NProto::TUnmountVolumeResponse>();
};

client->WriteBlocksLocalHandler =
[](std::shared_ptr<NProto::TWriteBlocksLocalRequest> request)
{
Y_UNUSED(request);

NProto::TError result = MakeError(
E_IO_SILENT,
"IO error",
NCloud::NProto::EF_HW_PROBLEMS_DETECTED);
return MakeFuture<NProto::TWriteBlocksLocalResponse>(
TErrorResponse(std::move(result)));
};

auto bootstrap = CreateBootstrap(client);

auto session = bootstrap->GetSession();

bootstrap->Start();

{
auto res = session->MountVolume().GetValueSync();
UNIT_ASSERT_C(!HasError(res), res.GetError().GetMessage());
}

{
auto res = WriteBlocks(session);
UNIT_ASSERT(res.GetError().GetCode() == E_IO_SILENT);
UNIT_ASSERT(
res.GetError().GetFlags() ==
NCloud::NProto::EF_HW_PROBLEMS_DETECTED);
}

bootstrap->Stop();
}
}

} // namespace NCloud::NBlockStore::NClient
36 changes: 22 additions & 14 deletions cloud/storage/core/libs/common/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,10 @@ concept TAcceptsError = requires(T a)
};

template <typename T>
T ErrorResponse(ui32 code, TString message)
T ErrorResponse(ui32 code, TString message, ui32 flags = 0)
{
T response;
*response.MutableError() = MakeError(code, std::move(message));
*response.MutableError() = MakeError(code, std::move(message), flags);
return response;
}

Expand Down Expand Up @@ -390,40 +390,48 @@ class TResultOrError<void>
class TErrorResponse
{
private:
const ui32 Code;
const TString Message;
NProto::TError Error;

public:
TErrorResponse(ui32 code, TString message = {})
: Code(code)
, Message(std::move(message))
TErrorResponse(ui32 code, TString message = {}, ui32 flags = 0)
: Error(MakeError(code, std::move(message), flags))
{}

TErrorResponse(const NProto::TError& e)
: Code(e.GetCode())
, Message(e.GetMessage())
: Error(e)
{}

TErrorResponse(NProto::TError&& e)
: Error(std::move(e))
{}

TErrorResponse(const TServiceError& e)
: Code(e.GetCode())
, Message(e.GetMessage())
: Error(MakeError(e.GetCode(), TString(e.GetMessage())))
{}

template <TAcceptsError T>
operator T() const
{
return ErrorResponse<T>(Code, Message);
return ErrorResponse<T>(
Error.GetCode(),
Error.GetMessage(),
Error.GetFlags());
}

template <typename T>
operator TResultOrError<T>() const
{
return MakeError(Code, Message);
return TResultOrError<T>(Error);
}

operator NProto::TError() const
{
return MakeError(Code, Message);
return Error;
}

operator NProto::TError&& () &&
{
return std::move(Error);
}
};

Expand Down

0 comments on commit 0ab2620

Please sign in to comment.