sdbus++: events: create json for events
Create JSON for the events containing their metadata and leverage that
as the "message" portion of the `sd_bus_error`. This will allow
unpacking the message on a client side back to the original exception.
Tested:
```
$ busctl --user call net.poettering.Calculator /net/poettering/calculator net.poettering.Calculator Divide xx 5 0
Call failed: {"net.poettering.Calculator.DivisionByZero":{"FOO":"unused"}}
```
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I4edd76d983267f28e51c4aa41902d45f5d6da793
diff --git a/.gitignore b/.gitignore
index c4fa618..b67be58 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
# Meson build directories.
/build*/
-/subprojects/*/
+/subprojects/*
+!/subprojects/*.wrap
# Created by https://www.toptal.com/developers/gitignore/api/python
# Edit at https://www.toptal.com/developers/gitignore?templates=python
diff --git a/include/sdbusplus/exception.hpp b/include/sdbusplus/exception.hpp
index 0ba477c..a8707f6 100644
--- a/include/sdbusplus/exception.hpp
+++ b/include/sdbusplus/exception.hpp
@@ -2,6 +2,7 @@
#include <systemd/sd-bus.h>
+#include <nlohmann/json_fwd.hpp>
#include <sdbusplus/sdbus.hpp>
#include <sdbusplus/utility/consteval_string.hpp>
@@ -72,6 +73,9 @@
template <utility::details::consteval_string_holder V>
using metadata_t = utility::consteval_string<V>;
+
+ protected:
+ mutable std::string jsonString;
};
/** base exception class for all errors generated by sdbusplus itself. */
diff --git a/meson.build b/meson.build
index 52e330a..598ad64 100644
--- a/meson.build
+++ b/meson.build
@@ -12,6 +12,7 @@
)
libsystemd_pkg = dependency('libsystemd')
+nlohmann_json_dep = dependency('nlohmann_json', include_type: 'system')
python = import('python')
python_bin = python.find_installation('python3', modules:['inflection', 'yaml', 'mako'])
@@ -40,7 +41,10 @@
'sdbusplus',
libsdbusplus_src,
include_directories: root_inc,
- dependencies: libsystemd_pkg,
+ dependencies: [
+ libsystemd_pkg,
+ nlohmann_json_dep
+ ],
version: meson.project_version(),
install: true,
)
@@ -60,7 +64,11 @@
sdbusplus_dep = declare_dependency(
include_directories: root_inc,
link_with: libsdbusplus,
- dependencies: [ libsystemd_pkg, boost_dep ],
+ dependencies: [
+ boost_dep,
+ libsystemd_pkg,
+ nlohmann_json_dep,
+ ],
)
subdir('tools')
diff --git a/subprojects/nlohmann_json.wrap b/subprojects/nlohmann_json.wrap
new file mode 100644
index 0000000..3745380
--- /dev/null
+++ b/subprojects/nlohmann_json.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+revision = HEAD
+url = https://github.com/nlohmann/json.git
+
+[provide]
+nlohmann_json = nlohmann_json_dep
diff --git a/tools/sdbusplus/templates/event.cpp.mako b/tools/sdbusplus/templates/event.cpp.mako
index e69de29..b956fa4 100644
--- a/tools/sdbusplus/templates/event.cpp.mako
+++ b/tools/sdbusplus/templates/event.cpp.mako
@@ -0,0 +1,28 @@
+int ${event.CamelCase}::set_error(sd_bus_error* e) const
+{
+ if (jsonString.empty())
+ {
+ jsonString = to_json().dump();
+ }
+
+ return sd_bus_error_set(e, errName, jsonString.c_str());
+}
+
+int ${event.CamelCase}::set_error(SdBusInterface* i, sd_bus_error* e) const
+{
+ if (jsonString.empty())
+ {
+ jsonString = to_json().dump();
+ }
+
+ return i->sd_bus_error_set(e, errName, jsonString.c_str());
+}
+
+auto ${event.CamelCase}::to_json() const -> nlohmann::json
+{
+ nlohmann::json j = { };
+% for m in event.metadata:
+ j["${m.SNAKE_CASE}"] = ${m.camelCase};
+% endfor
+ return nlohmann::json{ { errName, std::move(j) } };
+}
diff --git a/tools/sdbusplus/templates/event.hpp.mako b/tools/sdbusplus/templates/event.hpp.mako
index 24bc819..5425d0a 100644
--- a/tools/sdbusplus/templates/event.hpp.mako
+++ b/tools/sdbusplus/templates/event.hpp.mako
@@ -12,10 +12,14 @@
{}
%for m in event.metadata:
- ${m.cppTypeParam(events.name)} ${m.camelCase};
+ const ${m.cppTypeParam(events.name)} ${m.camelCase};
%endfor
%endif
+ int set_error(sd_bus_error*) const override;
+ int set_error(SdBusInterface*, sd_bus_error*) const override;
+ auto to_json() const -> nlohmann::json;
+
static constexpr auto errName =
"${events.name}.${event.name}";
static constexpr auto errDesc =
diff --git a/tools/sdbusplus/templates/events.cpp.mako b/tools/sdbusplus/templates/events.cpp.mako
index e69de29..737d5bd 100644
--- a/tools/sdbusplus/templates/events.cpp.mako
+++ b/tools/sdbusplus/templates/events.cpp.mako
@@ -0,0 +1,25 @@
+#include <${events.headerFile("event")}>
+#include <nlohmann/json.hpp>
+
+%if events.errors:
+
+namespace sdbusplus::error::${events.cppNamespacedClass()}
+{
+% for e in events.errors:
+
+${events.render(loader, "event.cpp.mako", events=events, event=e)}\
+% endfor
+
+} // namespace sdbusplus::error::${events.cppNamespacedClass()}
+%endif
+%if events.errors:
+
+namespace sdbusplus::event::${events.cppNamespacedClass()}
+{
+% for e in events.events:
+
+${events.render(loader, "event.cpp.mako", events=events, event=e)}\
+% endfor
+
+} // namespace sdbusplus::event::${events.cppNamespacedClass()}
+%endif