Skip to content

Commit 2e3deb9

Browse files
authored
[CONFIGURATION] File configuration - handle invalid YAML (#3858)
1 parent 0869455 commit 2e3deb9

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

sdk/include/opentelemetry/sdk/configuration/ryml_document.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class RymlDocument : public Document
2222
public:
2323
static std::unique_ptr<Document> Parse(const std::string &source, const std::string &content);
2424

25-
RymlDocument() {}
25+
RymlDocument() : event_handler_(MakeCallbacks()) {}
2626
RymlDocument(RymlDocument &&) = delete;
2727
RymlDocument(const RymlDocument &) = delete;
2828
RymlDocument &operator=(RymlDocument &&) = delete;
@@ -36,6 +36,12 @@ class RymlDocument : public Document
3636
DocumentNodeLocation Location(ryml::ConstNodeRef node) const;
3737

3838
private:
39+
static ryml::Callbacks MakeCallbacks();
40+
[[noreturn]] static void OnError(const char *msg,
41+
size_t msg_len,
42+
ryml::Location location,
43+
void *user_data);
44+
3945
ryml::ParserOptions opts_;
4046
ryml::Parser::handler_type event_handler_;
4147
std::unique_ptr<ryml::Parser> parser_;

sdk/src/configuration/ryml_document.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright The OpenTelemetry Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4+
#include <stddef.h>
45
#include <exception>
56
#include <memory>
67
#include <ostream>
@@ -11,6 +12,7 @@
1112
#include "opentelemetry/sdk/common/global_log_handler.h"
1213
#include "opentelemetry/sdk/configuration/document.h"
1314
#include "opentelemetry/sdk/configuration/document_node.h"
15+
#include "opentelemetry/sdk/configuration/invalid_schema_exception.h"
1416
#include "opentelemetry/sdk/configuration/ryml_document.h"
1517
#include "opentelemetry/sdk/configuration/ryml_document_node.h"
1618
#include "opentelemetry/version.h"
@@ -21,6 +23,30 @@ namespace sdk
2123
namespace configuration
2224
{
2325

26+
// Custom ryml error callback that throws instead of calling abort().
27+
// This ensures the try-catch in ParseDocument works regardless of how
28+
// ryml was compiled (with or without RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS).
29+
void RymlDocument::OnError(const char *msg,
30+
size_t msg_len,
31+
ryml::Location location,
32+
void * /*user_data*/)
33+
{
34+
DocumentNodeLocation loc;
35+
loc.offset = location.offset;
36+
loc.line = location.line;
37+
loc.col = location.col;
38+
loc.filename = std::string(location.name.str, location.name.len);
39+
40+
throw InvalidSchemaException(loc, std::string(msg, msg_len));
41+
}
42+
43+
ryml::Callbacks RymlDocument::MakeCallbacks()
44+
{
45+
ryml::Callbacks cb = ryml::get_callbacks();
46+
cb.m_error = &RymlDocument::OnError;
47+
return cb;
48+
}
49+
2450
std::unique_ptr<Document> RymlDocument::Parse(const std::string &source, const std::string &content)
2551
{
2652
auto doc = std::make_unique<RymlDocument>();

sdk/test/configuration/yaml_test.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,3 +717,26 @@ file_format: "1.0"
717717
auto config = DoParse(yaml);
718718
ASSERT_EQ(config, nullptr);
719719
}
720+
721+
TEST(Yaml, malformed_yaml)
722+
{
723+
// "headers" is indented under "client_certificate" instead of "otlp_http"
724+
std::string yaml = R"(
725+
file_format: "1.0"
726+
tracer_provider:
727+
processors:
728+
- simple:
729+
exporter:
730+
otlp_http:
731+
endpoint: http://localhost:4318/v1/traces
732+
certificate: /app/cert.pem
733+
client_key: /app/cert.pem
734+
client_certificate: /app/cert.pem
735+
headers:
736+
- name: header_name
737+
value: header_value
738+
)";
739+
740+
auto config = DoParse(yaml);
741+
ASSERT_EQ(config, nullptr);
742+
}

0 commit comments

Comments
 (0)