Home > database >  Error code to string? Struct to json with error_message
Error code to string? Struct to json with error_message

Time:11-27

Im developing a program in C that returns info from a DLL to be used in a webpage. The DLL returns a big struct with information but only need some fields that i plan to return as a json using https://github.com/nlohmann/json and then to char*.

Here is an example of the struct and the meaning of the values of each field (acording to the documentation pdf)

struct myStruct {
  BYTE StatusCode;
  BYTE ErrorCode;
  DWORD WarningCode[2];
  otherStruct SystemInfo[16];
  ...
}

StatusCode:  
0x00 = No Error
0x01 = Error
0x02 = Ready
... 
0x05 = Power Off

WarningCode
0x00 0x00 = No warning
0x02 0x01 = Warning Alert
... etc

Here is how i access the fields of the struct:

GetInfoStatus(&myStatusStruct);

jInfo["error_code"] = myStatusStruct.ErrorCode;
jInfo["status_code"] = myStatusStruct.StatusCode;
jInfo["warning_code"] = myStatusStruct.WarningCode2;
jInfo["is_available_warning_code"] = myStatusStruct.AvailableWarningCode2;

std::string info = jInfo.dump();
return info.c_str();

// My current return char* "json"
// {"available_warning_code":1,"error_code":255,"status_code":4}

But i would like to have something like this

{"available_warning_code": [0x01, "warning_alert"], "error_code": [0x01, "error_system_fail"], "status_code": [0x04, "low_battery"]}

Or similar so i can return also an error code to a "string" or "error_message" that indicates the meaning (a traslation) so my backend/frontend (NodeJS) later can detect "low_battery" and do something about it, instead of having to match 0x04 to a table to understand a 0x04 (that is different from other 0x04 in other key)

Ive checked this solution https://stackoverflow.com/a/208003/4620644 but still dont understand if is the best for my case and how to implement it. I have like 20 error codes, 10 warning codes, 15 status codes.

CodePudding user response:

You could create a std:pair and use that in the json. Somewhere, though, you are going to have to type out all the error messages.

#include <iostream>
#include <vector>
#include <string>
#include <utility>

#include "json.h"
using namespace nlohmann;

std::pair<int, std::string> make_error(int error)
{
    // Use a vector if error codes are sequential
    // Otherwise, maybe a switch
    std::vector<std::string> error_msgs = {
        "No Error", "Error", "Ready"
    };
    if (error >= 0 && error < error_msgs.size()) {
        return std::make_pair(error, error_msgs[error]);
    }
    else {
        return std::make_pair(error, "Unknown");
    }
}

int main()
{
    json jInfo;
    jInfo["error_code"] = make_error(2);
    std::cout << jInfo.dump();

    return 0;
}

This outputs:

{"error_code":[2,"Ready"]}

You'll have to do this for the other fields as well.

CodePudding user response:

To get error string

class CodeMap {
    map<pair<int, int>, string> m_warningCodes {
        {make_pair(0,0), "No warning"},
        {make_pair(2,1), "Warning Alert"}
    };
    
    map<int, string> m_statusCode{
        {0, "No Error"},
        {1, "Error"},
        {2, "Ready"},
        {5, "Power Off"},
    };

    public:
    std::string GetWarningCode(int code[]){
        return m_warningCodes[make_pair(code[0], code[1])];
    }

    std::string GetStatusCode(int code){
        return m_statusCode[code];
    }
};

Hexadecimal in json do not comply to RFC 7159

https://github.com/nlohmann/json/issues/249


Approach 1: Hex as string

To get hex from int type

//with c   20 std::format can be used instead below function
std::string GetHex(int i) {
    std::stringstream stream;
    stream << "0x" <<std::hex << i;
    return stream.str();
}

Assign key value pair to json field

CodeMap m; //To get message string
jInfo["error_code"] = make_pair(GetHex(myStatusStruct.ErrorCode), "error_system_fail");
jInfo["status_code"] = make_pair(GetHex(myStatusStruct.StatusCode), m.GetStatusCode(myStatusStruct.StatusCode));

output:

"error_code": ["0x01", "error_system_fail"], "status_code": ["0x04", "low_battery"]

Approach 2: Hex as integer

Assign key value pair to json field

CodeMap m; //To get message string

jInfo["error_code"] = make_pair(myStatusStruct.ErrorCode, "error_system_fail");
jInfo["status_code"] = make_pair(myStatusStruct.StatusCode, m.GetStatusCode(myStatusStruct.StatusCode));

output:

"error_code": [1, "error_system_fail"], "status_code": [4, "low_battery"]
  • Related