From 20dd88694ca0ec4fe197dd3efabc2625a4ed9230 Mon Sep 17 00:00:00 2001
From: Daniel Lyubomirov <daniel.lyubomirov@vereign.com>
Date: Mon, 15 Jun 2020 13:27:04 +0300
Subject: [PATCH] Add vereign_error code and message methods

---
 cpp/include/vereign/vereign.h             | 16 ++++++++++++++++
 cpp/src/vereign/vereign.cc                | 13 +++++++++++++
 cpp/tests/integration/integration_test.cc |  5 +++++
 cpp/vendor/fmt.cmake                      |  1 +
 4 files changed, 35 insertions(+)

diff --git a/cpp/include/vereign/vereign.h b/cpp/include/vereign/vereign.h
index 444ea0f..ab8ac98 100644
--- a/cpp/include/vereign/vereign.h
+++ b/cpp/include/vereign/vereign.h
@@ -42,6 +42,22 @@ typedef struct vereign_error vereign_error;
  */
 PUBLIC_API void vereign_error_free(vereign_error* err);
 
+/**
+ * Returns error object's code.
+ *
+ * @param err The error object.
+ * @returns the error code.
+ */
+PUBLIC_API int vereign_error_code(vereign_error* err);
+
+/**
+ * Returns error object's message.
+ *
+ * @param err The error object.
+ * @returns the error message.
+ */
+PUBLIC_API const char* vereign_error_message(vereign_error* err);
+
 /**
  * Provides the gRPC API services.
  *
diff --git a/cpp/src/vereign/vereign.cc b/cpp/src/vereign/vereign.cc
index aa69b13..842dedc 100644
--- a/cpp/src/vereign/vereign.cc
+++ b/cpp/src/vereign/vereign.cc
@@ -10,6 +10,14 @@ void vereign_error_free(vereign_error* err) {
   delete err;
 }
 
+auto vereign_error_code(vereign_error* err) -> int {
+  return err->code;
+}
+
+auto vereign_error_message(vereign_error* err) -> const char* {
+  return err->msg.data();
+}
+
 struct vereign_service {
   std::unique_ptr<vereign::grpc::Server> impl;
 };
@@ -21,7 +29,12 @@ auto vereign_service_start(
   const char* public_key,
   vereign_error** err
 ) -> vereign_service* {
+  if (err != nullptr) {
+    *err = nullptr;
+  }
+
   std::unique_ptr<vereign::grpc::Server> serviceImpl;
+
   try {
     serviceImpl = std::make_unique<vereign::grpc::Server>(
       listen_address,
diff --git a/cpp/tests/integration/integration_test.cc b/cpp/tests/integration/integration_test.cc
index dddb58f..ef42c72 100644
--- a/cpp/tests/integration/integration_test.cc
+++ b/cpp/tests/integration/integration_test.cc
@@ -12,6 +12,7 @@ TEST_CASE("C API integration", "[.integration]") {
   auto host = vereign::test::RequireEnv("TEST_VEREIGN_API_HOST");
   auto port = vereign::test::GetEnv("TEST_VEREIGN_API_PORT", "https");
 
+  // start the service
   vereign_error* err = nullptr;
   auto service = vereign_service_start(
     "localhost:",
@@ -28,6 +29,7 @@ TEST_CASE("C API integration", "[.integration]") {
 
   int listen_port = vereign_service_selected_port(service);
 
+  // start using the gRPC API with a C++ gRPC client.
   auto channel = ::grpc::CreateChannel(
     "localhost:" + std::to_string(listen_port),
     ::grpc::InsecureChannelCredentials()
@@ -116,6 +118,9 @@ TEST_CASE("vereign_service_start") {
 
     CHECK(service == nullptr);
     CHECK(err != nullptr);
+    CHECK(vereign_error_code(err) == VEREIGN_ERR_GRPC_BIND_FAILED);
+    std::string error_message = vereign_error_message(err);
+    CHECK(error_message == "gRPC listen failed");
 
     vereign_error_free(err);
     vereign_service_shutdown(service);
diff --git a/cpp/vendor/fmt.cmake b/cpp/vendor/fmt.cmake
index 3fd86d8..804c049 100644
--- a/cpp/vendor/fmt.cmake
+++ b/cpp/vendor/fmt.cmake
@@ -30,6 +30,7 @@ ExternalProject_Add(fmtlib
   -DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG}
   -DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE}
   -DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE}
+  -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON
   -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
   -DFMT_TEST:BOOL=OFF
 )
-- 
GitLab