Skip to content

Commit

Permalink
Add an error formatter for StatusIB encapsulated in CHIP_ERROR. (#13568)
Browse files Browse the repository at this point in the history
  • Loading branch information
bzbarsky-apple authored Jan 18, 2022
1 parent 93bc7f7 commit faa6043
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/app/InteractionModelEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ CHIP_ERROR InteractionModelEngine::Init(Messaging::ExchangeManager * apExchangeM

mMagic++;

StatusIB::RegisterErrorFormatter();

return CHIP_NO_ERROR;
}

Expand Down
46 changes: 46 additions & 0 deletions src/app/MessageDef/StatusIB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#include <stdio.h>

#include <app/AppBuildConfig.h>
#include <lib/core/CHIPCore.h>
#include <lib/support/ErrorStr.h>

using namespace chip;
using namespace chip::TLV;
Expand Down Expand Up @@ -183,5 +185,49 @@ void StatusIB::InitFromChipError(CHIP_ERROR aError)
mStatus = Status::Failure;
}

namespace {
bool FormatStatusIBError(char * buf, uint16_t bufSize, CHIP_ERROR err)
{
if (!err.IsIMStatus())
{
return false;
}

const char * desc = nullptr;
#if !CHIP_CONFIG_SHORT_ERROR_STR
constexpr char generalFormat[] = "General error: 0x%02" PRIx8;
constexpr char clusterFormat[] = "Cluster-specific error: 0x%02" PRIx8;

// Formatting an 8-bit int will take at most 2 chars, and replace the '%'
// and the format letter(s) for PRIx8, so a buffer big enough to hold our
// format string will also hold our formatted string.
constexpr size_t formattedSize = max(sizeof(generalFormat), sizeof(clusterFormat));
char formattedString[formattedSize];

StatusIB status;
status.InitFromChipError(err);
if (status.mClusterStatus.HasValue())
{
snprintf(formattedString, formattedSize, clusterFormat, status.mClusterStatus.Value());
}
else
{
snprintf(formattedString, formattedSize, generalFormat, to_underlying(status.mStatus));
}
desc = formattedString;
#endif // !CHIP_CONFIG_SHORT_ERROR_STR
FormatError(buf, bufSize, "IM", err, desc);

return true;
}
} // anonymous namespace

void StatusIB::RegisterErrorFormatter()
{
static ErrorFormatter sStatusIBErrorFormatter = { FormatStatusIBError, nullptr };

::RegisterErrorFormatter(&sStatusIBErrorFormatter);
}

}; // namespace app
}; // namespace chip
5 changes: 5 additions & 0 deletions src/app/MessageDef/StatusIB.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ struct StatusIB
*/
void InitFromChipError(CHIP_ERROR aError);

/**
* Register the StatusIB error formatter.
*/
static void RegisterErrorFormatter();

Protocols::InteractionModel::Status mStatus = Protocols::InteractionModel::Status::Success;
Optional<ClusterStatus> mClusterStatus = Optional<ClusterStatus>::Missing();

Expand Down
24 changes: 24 additions & 0 deletions src/app/tests/TestStatusIB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <app/MessageDef/StatusIB.h>
#include <lib/core/CHIPError.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/ErrorStr.h>
#include <lib/support/UnitTestRegistration.h>

#include <nlunit-test.h>
Expand Down Expand Up @@ -88,10 +89,30 @@ void TestStatusIBToFromChipError(nlTestSuite * aSuite, void * aContext)
}
}

#if !CHIP_CONFIG_SHORT_ERROR_STR
void TestStatusIBErrorToString(nlTestSuite * aSuite, void * aContext)
{
StatusIB status;
status.mStatus = Status::InvalidAction;
CHIP_ERROR err = status.ToChipError();
const char * str = ErrorStr(err);
NL_TEST_ASSERT(aSuite, strcmp(str, "IM Error 0x00000580: General error: 0x80") == 0);

status.mStatus = Status::Failure;
status.mClusterStatus = MakeOptional(static_cast<ClusterStatus>(5));
err = status.ToChipError();
str = ErrorStr(err);
NL_TEST_ASSERT(aSuite, strcmp(str, "IM Error 0x00000605: Cluster-specific error: 0x05") == 0);
}
#endif // !CHIP_CONFIG_SHORT_ERROR_STR

// clang-format off
const nlTest sTests[] =
{
NL_TEST_DEF("StatusIBToFromChipError", TestStatusIBToFromChipError),
#if !CHIP_CONFIG_SHORT_ERROR_STR
NL_TEST_DEF("StatusIBErrorToString", TestStatusIBErrorToString),
#endif // !CHIP_CONFIG_SHORT_ERROR_STR
NL_TEST_SENTINEL()
};
// clang-format on
Expand All @@ -105,6 +126,9 @@ static int TestSetup(void * inContext)
CHIP_ERROR error = chip::Platform::MemoryInit();
if (error != CHIP_NO_ERROR)
return FAILURE;
// Hand-register the error formatter. Normally it's registered by
// InteractionModelEngine::Init, but we don't want to mess with that here.
StatusIB::RegisterErrorFormatter();
return SUCCESS;
}

Expand Down

0 comments on commit faa6043

Please sign in to comment.