[price-quotes] Handle short error strings from finance-quote-wrapper.

This keeps the translation work in GnuCash and improves the error
signalling in gnc-quotes.
This commit is contained in:
John Ralls 2022-10-13 17:59:14 -07:00
parent fe9b23ff2b
commit 7f2a09a69f
2 changed files with 93 additions and 16 deletions

View File

@ -136,6 +136,7 @@ private:
static void show_quotes(const bpt::ptree& pt, const StrVec& commodities, bool verbose);
static void show_currency_quotes(const bpt::ptree& pt, const StrVec& commodities, bool verbose);
static std::string parse_quotesource_error(const std::string& line);
static const std::string empty_string{};
@ -293,16 +294,9 @@ GncQuotesImpl::fetch (CommVec& commodities)
m_failures.clear();
if (commodities.empty())
throw (GncQuoteException(bl::translate("GncQuotes::Fetch called with no commodities.")));
try
{
auto quote_str{query_fq (commodities)};
auto ptree{parse_quotes (quote_str)};
create_quotes(ptree, commodities);
}
catch (const GncQuoteException& err)
{
std::cerr << _("Finance::Quote retrieval failed with error ") << err.what() << std::endl;
}
auto quote_str{query_fq (commodities)};
auto ptree{parse_quotes (quote_str)};
create_quotes(ptree, commodities);
}
void
@ -436,7 +430,12 @@ get_quotes(const std::string& json_str, const std::unique_ptr<GncQuoteSource>& q
{
std::string err_str;
for (auto line: errors)
err_str.append(line + "\n");
{
if (line == "invalid_json\n")
PERR("Finanace Quote Wrapper was unable to parse %s",
json_str.c_str());
err_str += parse_quotesource_error(line);
}
throw(GncQuoteException(err_str));
}
@ -874,6 +873,32 @@ show_currency_quotes(const bpt::ptree& pt, const StrVec& commodities, bool verbo
std::cout << std::endl;
}
}
static std::string
parse_quotesource_error(const std::string& line)
{
std::string err_str;
if (line == "invalid_json\n")
{
err_str += _("GnuCash submitted invalid json to Finance::Quote. The details were logged.");
}
else if (line.substr(0, 15) == "missing_modules")
{
PERR("Missing Finance::Quote Dependencies: %s",
line.substr(17).c_str());
err_str += _("Perl is missing the following modules. Please see https://wiki.gnucash.org/wiki/Online_Quotes#Finance::Quote for detailed corrective action. ");
err_str += line.substr(17);
}
else
{
PERR("Unrecognized Finance::Quote Error %s", line.c_str());
err_str +=_("Unrecognized Finance::Quote Error: ");
err_str += line;
}
err_str += "\n";
return err_str;
}
/********************************************************************
* gnc_quotes_get_quotable_commodities
* list commodities in a given namespace that get price quotes

View File

@ -53,16 +53,35 @@ public:
GncMockQuoteSource(StrVec&& quotes, StrVec&& errors) :
m_quotes{std::move(quotes)}, m_errors{std::move(errors)}{}
~GncMockQuoteSource() override = default;
virtual const std::string& get_version() const noexcept override { return m_version; }
virtual const StrVec& get_sources() const noexcept override { return m_sources; }
virtual QuoteResult get_quotes(const std::string&) const override;
virtual bool usable() const noexcept override { return true; }
const std::string& get_version() const noexcept override { return m_version; }
const StrVec& get_sources() const noexcept override { return m_sources; }
QuoteResult get_quotes(const std::string&) const override;
};
class GncFailedQuoteSource final : public GncQuoteSource
{
const std::string m_version{"0"};
const StrVec m_sources;
public:
GncFailedQuoteSource()
{
std::string err{"Failed to initialize Finance::Quote: "};
err += "missing_modules Mozilla::CA Try::Tiny";
throw GncQuoteSourceError (err);
}
~GncFailedQuoteSource() override = default;
const std::string& get_version() const noexcept override { return m_version; }
const StrVec& get_sources() const noexcept override { return m_sources; }
QuoteResult get_quotes(const std::string&) const override {return {0, {}, {}}; }
};
QuoteResult
GncMockQuoteSource::get_quotes(const std::string& json_string) const
{
return {0, m_quotes, m_errors};
if (m_errors.empty())
return {0, m_quotes, m_errors};
return {1, m_quotes, m_errors};
}
class GncQuotesTest : public ::testing::Test
@ -357,3 +376,36 @@ TEST_F(GncQuotesTest, test_version)
GncQuotesImpl quotes(m_book, std::make_unique<GncMockQuoteSource>(std::move(quote_vec), std::move(err_vec)));
EXPECT_STREQ("9.99", quotes.version().c_str());
}
TEST_F(GncQuotesTest, test_failure_invalid_json)
{
StrVec quote_vec, err_vec{"invalid_json\n"};
GncQuotesImpl quotes(m_book, std::make_unique<GncMockQuoteSource>(std::move(quote_vec), std::move(err_vec)));
EXPECT_THROW(quotes.fetch(m_book), GncQuoteException);
try
{
quotes.fetch(m_book);
}
catch (const GncQuoteException& err)
{
EXPECT_STREQ("GnuCash submitted invalid json to Finance::Quote. The details were logged.\n",
err.what());
}
}
TEST_F(GncQuotesTest, test_failure_missing_modules)
{
EXPECT_THROW(GncQuotesImpl quotes(m_book, std::make_unique<GncFailedQuoteSource>()),
GncQuoteSourceError);
try
{
GncQuotesImpl quotes(m_book, std::make_unique<GncFailedQuoteSource>());
}
catch (const GncQuoteSourceError& err)
{
EXPECT_STREQ("Failed to initialize Finance::Quote: missing_modules Mozilla::CA Try::Tiny",
err.what());
}
}