mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-30 03:17:08 +00:00
Throw std::invalid_argument for deserialization type error
This commit is contained in:
parent
b0bf107f71
commit
556f32ec1b
@ -155,7 +155,13 @@ std::unique_ptr<BaseIpcMessage> MessageRegistry::Parse(Reader& visitor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Allocator& allocator = allocators[method];
|
Allocator& allocator = allocators[method];
|
||||||
|
// FIXME Print error message for deserialization error
|
||||||
|
try {
|
||||||
return allocator(visitor);
|
return allocator(visitor);
|
||||||
|
} catch (std::invalid_argument& e) {
|
||||||
|
LOG_S(ERROR) << "Unable to deserialize request '" << method << "'";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageRegistry* MessageRegistry::instance() {
|
MessageRegistry* MessageRegistry::instance() {
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <stdexcept>
|
||||||
|
|
||||||
// TODO Cleanup global variables
|
// TODO Cleanup global variables
|
||||||
extern std::string g_init_options;
|
extern std::string g_init_options;
|
||||||
@ -71,7 +71,18 @@ struct InitializeHandler : BaseMessageHandler<Ipc_InitializeRequest> {
|
|||||||
reader.Parse(g_init_options.c_str());
|
reader.Parse(g_init_options.c_str());
|
||||||
if (!reader.HasParseError()) {
|
if (!reader.HasParseError()) {
|
||||||
JsonReader json_reader{&reader};
|
JsonReader json_reader{&reader};
|
||||||
|
try {
|
||||||
Reflect(json_reader, *config);
|
Reflect(json_reader, *config);
|
||||||
|
} catch (std::invalid_argument& ex) {
|
||||||
|
// FIXME This is not triggered. Need to pass error from
|
||||||
|
// MessageRegistry::Parse in language_server_api.cc
|
||||||
|
Out_ShowLogMessage out;
|
||||||
|
out.display_type = Out_ShowLogMessage::DisplayType::Show;
|
||||||
|
out.params.type = lsMessageType::Error;
|
||||||
|
out.params.message = "Failed to deserialize " +
|
||||||
|
json_reader.GetPath() + " " + ex.what();
|
||||||
|
out.Write(std::cout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_enable_comments = config->enableComments;
|
g_enable_comments = config->enableComments;
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <doctest/doctest.h>
|
#include <doctest/doctest.h>
|
||||||
#include <loguru.hpp>
|
#include <loguru.hpp>
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
bool gTestOutputMode = false;
|
bool gTestOutputMode = false;
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -15,6 +17,7 @@ bool gTestOutputMode = false;
|
|||||||
//// Elementary types
|
//// Elementary types
|
||||||
|
|
||||||
void Reflect(Reader& visitor, uint8_t& value) {
|
void Reflect(Reader& visitor, uint8_t& value) {
|
||||||
|
if (!visitor.IsInt()) throw std::invalid_argument("uint8_t");
|
||||||
value = (uint8_t)visitor.GetInt();
|
value = (uint8_t)visitor.GetInt();
|
||||||
}
|
}
|
||||||
void Reflect(Writer& visitor, uint8_t& value) {
|
void Reflect(Writer& visitor, uint8_t& value) {
|
||||||
@ -22,6 +25,7 @@ void Reflect(Writer& visitor, uint8_t& value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader& visitor, int16_t& value) {
|
void Reflect(Reader& visitor, int16_t& value) {
|
||||||
|
if (!visitor.IsInt()) throw std::invalid_argument("int16_t");
|
||||||
value = (int16_t)visitor.GetInt();
|
value = (int16_t)visitor.GetInt();
|
||||||
}
|
}
|
||||||
void Reflect(Writer& visitor, int16_t& value) {
|
void Reflect(Writer& visitor, int16_t& value) {
|
||||||
@ -29,6 +33,7 @@ void Reflect(Writer& visitor, int16_t& value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader& visitor, int& value) {
|
void Reflect(Reader& visitor, int& value) {
|
||||||
|
if (!visitor.IsInt()) throw std::invalid_argument("int");
|
||||||
value = visitor.GetInt();
|
value = visitor.GetInt();
|
||||||
}
|
}
|
||||||
void Reflect(Writer& visitor, int& value) {
|
void Reflect(Writer& visitor, int& value) {
|
||||||
@ -36,6 +41,7 @@ void Reflect(Writer& visitor, int& value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader& visitor, unsigned& value) {
|
void Reflect(Reader& visitor, unsigned& value) {
|
||||||
|
if (!visitor.IsInt()) throw std::invalid_argument("unsigned");
|
||||||
value = visitor.GetUint32();
|
value = visitor.GetUint32();
|
||||||
}
|
}
|
||||||
void Reflect(Writer& visitor, unsigned& value) {
|
void Reflect(Writer& visitor, unsigned& value) {
|
||||||
@ -43,6 +49,7 @@ void Reflect(Writer& visitor, unsigned& value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader& visitor, long& value) {
|
void Reflect(Reader& visitor, long& value) {
|
||||||
|
if (!visitor.IsInt64()) throw std::invalid_argument("long");
|
||||||
value = long(visitor.GetInt64());
|
value = long(visitor.GetInt64());
|
||||||
}
|
}
|
||||||
void Reflect(Writer& visitor, long& value) {
|
void Reflect(Writer& visitor, long& value) {
|
||||||
@ -50,6 +57,7 @@ void Reflect(Writer& visitor, long& value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader& visitor, unsigned long& value) {
|
void Reflect(Reader& visitor, unsigned long& value) {
|
||||||
|
if (!visitor.IsUint64()) throw std::invalid_argument("unsigned long");
|
||||||
value = (unsigned long)visitor.GetUint64();
|
value = (unsigned long)visitor.GetUint64();
|
||||||
}
|
}
|
||||||
void Reflect(Writer& visitor, unsigned long& value) {
|
void Reflect(Writer& visitor, unsigned long& value) {
|
||||||
@ -57,6 +65,7 @@ void Reflect(Writer& visitor, unsigned long& value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader& visitor, long long& value) {
|
void Reflect(Reader& visitor, long long& value) {
|
||||||
|
if (!visitor.IsInt64()) throw std::invalid_argument("long long");
|
||||||
value = visitor.GetInt64();
|
value = visitor.GetInt64();
|
||||||
}
|
}
|
||||||
void Reflect(Writer& visitor, long long& value) {
|
void Reflect(Writer& visitor, long long& value) {
|
||||||
@ -64,6 +73,7 @@ void Reflect(Writer& visitor, long long& value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader& visitor, unsigned long long& value) {
|
void Reflect(Reader& visitor, unsigned long long& value) {
|
||||||
|
if (!visitor.IsUint64()) throw std::invalid_argument("unsigned long long");
|
||||||
value = visitor.GetUint64();
|
value = visitor.GetUint64();
|
||||||
}
|
}
|
||||||
void Reflect(Writer& visitor, unsigned long long& value) {
|
void Reflect(Writer& visitor, unsigned long long& value) {
|
||||||
@ -71,6 +81,7 @@ void Reflect(Writer& visitor, unsigned long long& value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader& visitor, double& value) {
|
void Reflect(Reader& visitor, double& value) {
|
||||||
|
if (!visitor.IsDouble()) throw std::invalid_argument("double");
|
||||||
value = visitor.GetDouble();
|
value = visitor.GetDouble();
|
||||||
}
|
}
|
||||||
void Reflect(Writer& visitor, double& value) {
|
void Reflect(Writer& visitor, double& value) {
|
||||||
@ -78,6 +89,7 @@ void Reflect(Writer& visitor, double& value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Reflect(Reader& visitor, bool& value) {
|
void Reflect(Reader& visitor, bool& value) {
|
||||||
|
if (!visitor.IsBool()) throw std::invalid_argument("bool");
|
||||||
value = visitor.GetBool();
|
value = visitor.GetBool();
|
||||||
}
|
}
|
||||||
void Reflect(Writer& visitor, bool& value) {
|
void Reflect(Writer& visitor, bool& value) {
|
||||||
@ -86,7 +98,7 @@ void Reflect(Writer& visitor, bool& value) {
|
|||||||
|
|
||||||
// std::string
|
// std::string
|
||||||
void Reflect(Reader& visitor, std::string& value) {
|
void Reflect(Reader& visitor, std::string& value) {
|
||||||
if (visitor.IsString())
|
if (!visitor.IsString()) throw std::invalid_argument("std::string");
|
||||||
value = visitor.GetString();
|
value = visitor.GetString();
|
||||||
}
|
}
|
||||||
void Reflect(Writer& visitor, std::string& value) {
|
void Reflect(Writer& visitor, std::string& value) {
|
||||||
@ -289,7 +301,14 @@ std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
|
|||||||
|
|
||||||
file = MakeUnique<IndexFile>(path, nullopt);
|
file = MakeUnique<IndexFile>(path, nullopt);
|
||||||
JsonReader json_reader{&reader};
|
JsonReader json_reader{&reader};
|
||||||
|
try {
|
||||||
Reflect(json_reader, *file);
|
Reflect(json_reader, *file);
|
||||||
|
} catch (std::invalid_argument& e) {
|
||||||
|
LOG_S(ERROR) << "'" << path << "': failed to deserialize "
|
||||||
|
<< json_reader.GetPath() << "."
|
||||||
|
<< e.what();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,12 +19,13 @@ class Reader {
|
|||||||
virtual ~Reader() {}
|
virtual ~Reader() {}
|
||||||
virtual SerializeFormat Format() const = 0;
|
virtual SerializeFormat Format() const = 0;
|
||||||
|
|
||||||
// virtual bool IsBool() = 0;
|
virtual bool IsBool() = 0;
|
||||||
virtual bool IsNull() = 0;
|
virtual bool IsNull() = 0;
|
||||||
virtual bool IsArray() = 0;
|
virtual bool IsArray() = 0;
|
||||||
virtual bool IsInt() = 0;
|
virtual bool IsInt() = 0;
|
||||||
virtual bool IsInt64() = 0;
|
virtual bool IsInt64() = 0;
|
||||||
// virtual bool IsUint64() = 0;
|
virtual bool IsUint64() = 0;
|
||||||
|
virtual bool IsDouble() = 0;
|
||||||
virtual bool IsString() = 0;
|
virtual bool IsString() = 0;
|
||||||
|
|
||||||
virtual void GetNull() = 0;
|
virtual void GetNull() = 0;
|
||||||
|
@ -7,17 +7,19 @@
|
|||||||
|
|
||||||
class JsonReader : public Reader {
|
class JsonReader : public Reader {
|
||||||
rapidjson::GenericValue<rapidjson::UTF8<>>* m_;
|
rapidjson::GenericValue<rapidjson::UTF8<>>* m_;
|
||||||
|
std::vector<const char*> path_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JsonReader(rapidjson::GenericValue<rapidjson::UTF8<>>* m) : m_(m) {}
|
JsonReader(rapidjson::GenericValue<rapidjson::UTF8<>>* m) : m_(m) {}
|
||||||
SerializeFormat Format() const override { return SerializeFormat::Json; }
|
SerializeFormat Format() const override { return SerializeFormat::Json; }
|
||||||
|
|
||||||
// bool IsBool() override { return m_->IsBool(); }
|
bool IsBool() override { return m_->IsBool(); }
|
||||||
bool IsNull() override { return m_->IsNull(); }
|
bool IsNull() override { return m_->IsNull(); }
|
||||||
bool IsArray() override { return m_->IsArray(); }
|
bool IsArray() override { return m_->IsArray(); }
|
||||||
bool IsInt() override { return m_->IsInt(); }
|
bool IsInt() override { return m_->IsInt(); }
|
||||||
bool IsInt64() override { return m_->IsInt64(); }
|
bool IsInt64() override { return m_->IsInt64(); }
|
||||||
// bool IsUint64() override { return m_->IsUint64(); }
|
bool IsUint64() override { return m_->IsUint64(); }
|
||||||
|
bool IsDouble() override { return m_->IsDouble(); }
|
||||||
bool IsString() override { return m_->IsString(); }
|
bool IsString() override { return m_->IsString(); }
|
||||||
|
|
||||||
void GetNull() override {}
|
void GetNull() override {}
|
||||||
@ -36,22 +38,35 @@ class JsonReader : public Reader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IterArray(std::function<void(Reader&)> fn) override {
|
void IterArray(std::function<void(Reader&)> fn) override {
|
||||||
|
if (!m_->IsArray())
|
||||||
|
throw std::invalid_argument("array");
|
||||||
|
// Use "0" to indicate any element for now.
|
||||||
|
path_.push_back("0");
|
||||||
for (auto& entry : m_->GetArray()) {
|
for (auto& entry : m_->GetArray()) {
|
||||||
JsonReader sub(&entry);
|
JsonReader sub(&entry);
|
||||||
fn(sub);
|
fn(sub);
|
||||||
}
|
}
|
||||||
|
path_.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoMember(const char* name, std::function<void(Reader&)> fn) override {
|
void DoMember(const char* name, std::function<void(Reader&)> fn) override {
|
||||||
if (m_->GetType() != rapidjson::Type::kObjectType)
|
path_.push_back(name);
|
||||||
return; // FIXME: signal an error that object was not deserialized
|
|
||||||
// correctly?
|
|
||||||
|
|
||||||
auto it = m_->FindMember(name);
|
auto it = m_->FindMember(name);
|
||||||
if (it != m_->MemberEnd()) {
|
if (it != m_->MemberEnd()) {
|
||||||
JsonReader sub(&it->value);
|
JsonReader sub(&it->value);
|
||||||
fn(sub);
|
fn(sub);
|
||||||
}
|
}
|
||||||
|
path_.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetPath() const {
|
||||||
|
std::string ret;
|
||||||
|
for (auto& t : path_) {
|
||||||
|
ret += '/';
|
||||||
|
ret += t;
|
||||||
|
}
|
||||||
|
ret.pop_back();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ class MessagePackReader : public Reader {
|
|||||||
return SerializeFormat::MessagePack;
|
return SerializeFormat::MessagePack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsBool() override { return oh_.get().type == msgpack::type::BOOLEAN; }
|
||||||
bool IsNull() override { return oh_.get().is_nil(); }
|
bool IsNull() override { return oh_.get().is_nil(); }
|
||||||
bool IsArray() override { return oh_.get().type == msgpack::type::ARRAY; }
|
bool IsArray() override { return oh_.get().type == msgpack::type::ARRAY; }
|
||||||
bool IsInt() override {
|
bool IsInt() override {
|
||||||
@ -28,6 +29,8 @@ class MessagePackReader : public Reader {
|
|||||||
oh_.get().type == msgpack::type::NEGATIVE_INTEGER;
|
oh_.get().type == msgpack::type::NEGATIVE_INTEGER;
|
||||||
}
|
}
|
||||||
bool IsInt64() override { return IsInt(); }
|
bool IsInt64() override { return IsInt(); }
|
||||||
|
bool IsUint64() override { return IsInt(); }
|
||||||
|
bool IsDouble() override { return oh_.get().type == msgpack::type::FLOAT64; };
|
||||||
bool IsString() override { return oh_.get().type == msgpack::type::STR; }
|
bool IsString() override { return oh_.get().type == msgpack::type::STR; }
|
||||||
|
|
||||||
void GetNull() override { pk_->next(oh_); }
|
void GetNull() override { pk_->next(oh_); }
|
||||||
|
Loading…
Reference in New Issue
Block a user