bool CJsonOverUTTPWriter::SendNode(const CJsonNode& node)
{
    switch (node.GetNodeType()) {
    case CJsonNode::eObject:
        m_OutputStack.push_back(m_CurrentOutputNode);
        m_CurrentOutputNode.m_Node = node;
        m_CurrentOutputNode.m_ObjectIterator = node.GetObject().begin();
        m_SendHashValue = false;
        if (!m_UTTPWriter.SendControlSymbol('{'))
            return false;
        break;

    case CJsonNode::eArray:
        m_OutputStack.push_back(m_CurrentOutputNode);
        m_CurrentOutputNode.m_Node = node;
        m_CurrentOutputNode.m_ArrayIterator = node.GetArray().begin();
        if (!m_UTTPWriter.SendControlSymbol('['))
            return false;
        break;

    case CJsonNode::eString:
        {
            string str(node.GetString());
            if (!m_UTTPWriter.SendChunk(str.data(), str.length(), false))
                return false;
        }
        break;

    case CJsonNode::eNumber:
        if (!m_UTTPWriter.SendNumber(node.GetNumber()))
            return false;
        break;

    case CJsonNode::eBoolean:
        if (!m_UTTPWriter.SendControlSymbol(node.GetBoolean() ? 'Y' : 'N'))
            return false;
        break;

    case CJsonNode::eNull:
        if (!m_UTTPWriter.SendControlSymbol('U'))
            return false;
    }

    return true;
}
Example #2
0
static void s_TrapErrors(const CJsonNode& request,
        const CJsonNode& reply, CSocket& sock,
        SNetStorage::SConfig::EErrMode err_mode)
{
    const string server_address(sock.GetPeerAddress());
    CJsonNode issues(reply.GetByKeyOrNull("Warnings"));

    if (issues) {
        for (CJsonIterator it = issues.Iterate(); it; ++it) {
            const SIssue issue(*it);
            LOG_POST(Warning << "NetStorage server " << server_address <<
                    " issued warning " << issue);
        }
    }

    const string status = reply.GetString("Status");
    const bool status_ok = status == "OK";
    issues = reply.GetByKeyOrNull("Errors");

    // Got errors
    if (!status_ok || issues) {
        if (status_ok && err_mode != SNetStorage::SConfig::eThrow) {
            if (err_mode == SNetStorage::SConfig::eLog) {
                for (CJsonIterator it = issues.Iterate(); it; ++it) {
                    const SIssue issue(*it);
                    LOG_POST(Error << "NetStorage server " << server_address <<
                            " issued error " << issue);
                }
            }
        } else {
            Int8 code = CNetStorageServerError::eUnknownError;
            Int8 sub_code = SIssue::kEmptySubCode;
            ostringstream errors;

            if (!issues)
                errors << status;
            else {
                const char* prefix = "error ";

                for (CJsonIterator it = issues.Iterate(); it; ++it) {
                    const SIssue issue(*it);
                    code = issue.code;
                    sub_code = issue.sub_code;
                    errors << prefix << issue;
                    prefix = ", error ";
                }
            }

            string err_msg = FORMAT("Error while executing " <<
                            request.GetString("Type") << " "
                    "on NetStorage server " <<
                            sock.GetPeerAddress() << ". "
                    "Server returned " << errors.str());

            s_ThrowError(code, sub_code, err_msg);
        }
    }

    if (reply.GetInteger("RE") != request.GetInteger("SN")) {
        NCBI_THROW_FMT(CNetStorageException, eServerError,
                "Message serial number mismatch "
                "(NetStorage server: " << sock.GetPeerAddress() << "; "
                "request: " << request.Repr() << "; "
                "reply: " << reply.Repr() << ").");
    }
}