Add exception handling codes 99/207799/8
authorhyunho <hhstark.kang@samsung.com>
Thu, 13 Jun 2019 01:22:29 +0000 (10:22 +0900)
committerhyunho <hhstark.kang@samsung.com>
Wed, 3 Jul 2019 08:51:51 +0000 (17:51 +0900)
Change-Id: Ic523f578acc377108d47390240d11d096a3dc31f
Signed-off-by: hyunho <hhstark.kang@samsung.com>
15 files changed:
component_based/app_control/component_based_app_control.cc
component_based/app_control/component_based_app_control.h
component_based/base/action_internal.cc
component_based/base/application_base.cc
component_based/base/component.cc
component_based/base/component.h
component_based/base/component_implementation.h
component_based/base/component_manager_internal.cc
component_based/base/component_manager_internal.h
component_based/base/exception.h [deleted file]
component_based/base/frame_component.h
component_based/base/service_component.h
component_based/common/exception.h [new file with mode: 0644]
component_based/efl_base/stub.cc
unit_tests/src/base/test_component_based_component.cc

index 4f138f50691c41628f8b06a36f1e530bb2dd1400..b1846e76406ce52d2e871d31152b6fc0824cc7b6 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <memory>
 
+#include "component_based/common/exception.h"
 #include "component_based/app_control/component_based_app_control.h"
 #include "component_based/app_control/component_based_app_control_implementation.h"
 
@@ -78,36 +79,62 @@ AppControl::Builder& AppControl::Builder::SetComponentID(std::string comp_id) {
   return *this;
 }
 
-AppControl AppControl::Builder::Build() {
+app_control_h AppControl::Builder::BuildNative() {
   app_control_h handle = nullptr;
 
   app_control_create(&handle);
+  if (handle == nullptr)
+    return nullptr;
+
+  std::unique_ptr<std::remove_pointer<app_control_h>::type,
+      decltype(app_control_destroy)*> ptr(handle, app_control_destroy);
   if (!appid_.empty()) {
-    app_control_set_app_id(handle, appid_.c_str());
+    if (app_control_set_app_id(handle, appid_.c_str()) !=
+        APP_CONTROL_ERROR_NONE)
+      return nullptr;
   }
 
   if (!op_.empty()) {
-    app_control_set_operation(handle, op_.c_str());
+    if (app_control_set_operation(handle, op_.c_str()) !=
+        APP_CONTROL_ERROR_NONE)
+      return nullptr;
   }
 
   if (!mime_.empty()) {
-    app_control_set_mime(handle, mime_.c_str());
+    if (app_control_set_mime(handle, mime_.c_str()) !=
+        APP_CONTROL_ERROR_NONE)
+      return nullptr;
   }
 
-  app_control_set_uri(handle, uri_.Encode().c_str());
+  if (app_control_set_uri(handle, uri_.Encode().c_str()) !=
+      APP_CONTROL_ERROR_NONE)
+      return nullptr;
 
   for (auto& data : extra_) {
-    app_control_add_extra_data(handle, data.first.c_str(),
-        data.second.c_str());
+    if (app_control_add_extra_data(handle, data.first.c_str(),
+        data.second.c_str()) !=
+        APP_CONTROL_ERROR_NONE)
+      return nullptr;
   }
 
-  app_control_set_launch_mode(handle,
-      static_cast<app_control_launch_mode_e>(mode_));
+  if (app_control_set_launch_mode(handle,
+    static_cast<app_control_launch_mode_e>(mode_)) !=
+      APP_CONTROL_ERROR_NONE)
+      return nullptr;
 
   if (!comp_id_.empty()) {
-    app_control_set_component_id(handle, comp_id_.c_str());
+    if (app_control_set_component_id(handle, comp_id_.c_str()) !=
+        APP_CONTROL_ERROR_NONE)
+      return nullptr;
   }
+  return ptr.release();
+}
 
+AppControl AppControl::Builder::Build() {
+  app_control_h handle = BuildNative();
+  if (handle == nullptr) {
+    THROW(Exception::ErrorCodes::IOError);
+  }
   return AppControl(handle);
 }
 
@@ -120,14 +147,20 @@ AppControl::~AppControl() {
 
 AppControl::AppControl(const AppControl& control) {
   app_control_h handle = nullptr;
-  app_control_clone(&handle, control.impl_->handle_);
+  if (app_control_clone(&handle, control.impl_->handle_) !=
+      APP_CONTROL_ERROR_NONE) {
+    THROW(Exception::ErrorCodes::OutOfMemory);
+  }
   impl_ = std::unique_ptr<Impl>(new Impl(this, handle));
 }
 
 AppControl& AppControl::operator=(const AppControl& control) {
   if (this != &control) {
     app_control_h handle = nullptr;
-    app_control_clone(&handle, control.impl_->handle_);
+    if (app_control_clone(&handle, control.impl_->handle_) !=
+        APP_CONTROL_ERROR_NONE) {
+      THROW(Exception::ErrorCodes::OutOfMemory);
+    }
     impl_->handle_ = handle;
   }
   return *this;
@@ -216,7 +249,10 @@ AppControl::LaunchMode AppControl::GetLaunchMode() {
     return AppControl::LaunchMode::SINGLE;
 
   app_control_launch_mode_e launch_mode = APP_CONTROL_LAUNCH_MODE_SINGLE;
-  app_control_get_launch_mode(impl_->handle_, &launch_mode);
+  if (app_control_get_launch_mode(impl_->handle_, &launch_mode) !=
+      APP_CONTROL_ERROR_NONE) {
+    THROW(Exception::ErrorCodes::InvalidParameter);
+  }
   return static_cast<AppControl::LaunchMode>(launch_mode);
 }
 
index 892fc51b958d2165551eda659327a7fce0020a82..0e4c89b8f53f92534d0e988bc38773e797881c6f 100644 (file)
@@ -81,6 +81,9 @@ class EXPORT_API AppControl {
     Builder& SetComponentID(std::string comp_id);
     AppControl Build();
 
+   private:
+    app_control_h BuildNative();
+
    private:
     std::string appid_;
     std::string op_;
index 9b2f9ee58393b6ec0b1c79f631519068aaa034fe..779da66c12bc58f16afbc2d69939ec652e505b88 100644 (file)
  * limitations under the License.
  */
 
+#include <dlog.h>
+
 #include <memory>
 #include <string>
 
+#include "component_based/common/exception.h"
 #include "component_based/base/action_internal.h"
 
 namespace component_based {
@@ -24,7 +27,10 @@ namespace internal {
 
 Action::Action(std::string name, Action::IEventListener* ev)
   : ev_(ev) {
-  app_control_add_action_handler(name.c_str(), OnActionCB, ev_, &handle_);
+  if (app_control_add_action_handler(name.c_str(), OnActionCB, ev_, &handle_)
+      != APP_CONTROL_ERROR_NONE) {
+    THROW(Exception::ErrorCodes::InvalidParameter);
+  }
 }
 
 Action::~Action() {
@@ -35,7 +41,11 @@ Action::~Action() {
 void Action::OnActionCB(const char* action, app_control_h app_control,
                         void* user_data) {
   IEventListener* ev = static_cast<IEventListener*>(user_data);
-  ev->OnAction(std::string(action), AppControl(app_control));
+  try {
+    ev->OnAction(std::string(action), AppControl(app_control));
+  } catch(Exception& ex) {
+    LOGE("Exception occurred (%s)", ex.what());
+  }
 }
 
 }  // namespace internal
index a7a26ee2caa55d556a309652d16f0b6be8beaaa9..b1ed73ae8f9be76eb2e7c3823ccc39ea0d2f0e25 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <memory>
 
+#include "component_based/common/exception.h"
 #include "component_based/base/application_base_implementation.h"
 #include "component_based/base/application_base.h"
 #include "component_based/base/component_manager_internal.h"
@@ -37,10 +38,8 @@ ApplicationBase::Impl::Impl(ApplicationBase* parent)
   LOGD("");
   char* id = nullptr;
   int r = app_get_id(&id);
-  if (r != APP_ERROR_NONE) {
-    LOGE("Failed to get application ID");
-    return;
-  }
+  if (r != APP_ERROR_NONE)
+    THROW(Exception::ErrorCodes::IOError);
 
   auto p = std::unique_ptr<char, decltype(std::free)*>(id, std::free);
   app_id_ = std::string(p.get());
@@ -80,7 +79,12 @@ bool ApplicationBase::Impl::OnBaseCreate() {
     auto comp_id = i->first;
     auto factory = std::move(i->second);
     auto& mgr = internal::ComponentManager::GetInst();
-    mgr.RegisterComponent(std::move(comp_id), std::move(factory));
+    try {
+      mgr.RegisterComponent(std::move(comp_id), std::move(factory));
+    } catch(Exception& ex) {
+      LOGE("Exception occurred (%s)", ex.what());
+      throw;
+    }
   }
 
   return true;
index cc352ddff022776b5e4352d90fb5aaa0f2acf8d8..25bb68df251d240cb55a67be02bf6d09b9b35f3f 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <memory>
 
+#include "component_based/common/exception.h"
 #include "component_based/base/component.h"
 #include "component_based/base/component_implementation.h"
 #include "component_based/base/dlog_internal.h"
@@ -40,7 +41,11 @@ Component::Impl::Impl(Component* parent, Component::Type type,
 }
 
 bool Component::Impl::OnCreate() {
-  aul_comp_notify_start(inst_id_.c_str());
+  int ret = aul_comp_notify_start(inst_id_.c_str());
+  if (ret != AUL_R_OK) {
+    LOGE("Fail to start notify (%d)", ret);
+    return false;
+  }
 
   if (parent_->GetType() == Component::Type::Frame) {
     FrameComponent* component = static_cast<FrameComponent*>(parent_);
@@ -49,9 +54,19 @@ bool Component::Impl::OnCreate() {
       LOGE("OnCreate() returns nullptr");
       return false;
     }
+
     auto& mgr = internal::ComponentManager::GetInst();
-    mgr.Bind(component->GetInstanceID(), std::move(win));
-    aul_comp_status_update(inst_id_.c_str(), STATUS_CREATED);
+    if (!mgr.Bind(component->GetInstanceID(), std::move(win))) {
+      LOGE("Bind window fail");
+      return false;
+    }
+
+    ret = aul_comp_status_update(inst_id_.c_str(), STATUS_CREATED);
+    if (ret != AUL_R_OK) {
+      LOGE("Fail to update status (%d)", ret);
+      return false;
+    }
+
   } else {
     ServiceComponent* component = static_cast<ServiceComponent*>(parent_);
     bool r = component->OnCreate();
@@ -65,7 +80,12 @@ bool Component::Impl::OnCreate() {
 }
 
 void Component::Impl::OnDestroy() {
-  aul_comp_status_update(inst_id_.c_str(), STATUS_DYING);
+  int ret = aul_comp_status_update(inst_id_.c_str(), STATUS_DYING);
+  if (ret != AUL_R_OK) {
+    LOGE("Fail to update status (%d)", ret);
+    return;
+  }
+
   state_ = State::Dying;
   if (parent_->GetType() == Component::Type::Frame) {
     FrameComponent* component = static_cast<FrameComponent*>(parent_);
@@ -172,18 +192,27 @@ void Component::Impl::RegisterAction(std::string app_control_name) {
     return;
   }
 
-  act_map_[app_control_name] = std::unique_ptr<internal::Action>(
-      new internal::Action(app_control_name, this));
+  try {
+    std::unique_ptr<internal::Action> action = std::unique_ptr<internal::Action>(
+        new (std::nothrow) internal::Action(app_control_name, this));
+    if (action.get() == nullptr)
+      THROW(Exception::ErrorCodes::OutOfMemory);
+    act_map_[app_control_name] = std::move(action);
+  } catch(Exception& ex) {
+    LOGE("Exception occurred (%s)", ex.what());
+    throw;
+  }
 }
 
-void Component::Impl::DeregisterAction(std::string app_control_name) {
+bool Component::Impl::DeregisterAction(std::string app_control_name) {
   auto act_iter = act_map_.find(app_control_name);
   if (act_iter == act_map_.end()) {
     LOGW("Not found");
-    return;
+    return false;
   }
 
   act_map_.erase(app_control_name);
+  return true;
 }
 
 void Component::Impl::OnAppControlReply(app_control_h request,
@@ -196,8 +225,12 @@ void Component::Impl::OnAppControlReply(app_control_h request,
   app_control_clone(&request_handle, request);
   app_control_h reply_handle = nullptr;
   app_control_clone(&reply_handle, reply);
-  ev->OnReplyReceived(AppControl(request_handle), AppControl(reply_handle),
-      static_cast<AppControl::Result>(result));
+  try {
+    ev->OnReplyReceived(AppControl(request_handle), AppControl(reply_handle),
+        static_cast<AppControl::Result>(result));
+  } catch(Exception& ex) {
+    LOGE("Exception occurred (%s)", ex.what());
+  }
 }
 
 void Component::Impl::OnAppControlResult(app_control_h request,
@@ -207,59 +240,63 @@ void Component::Impl::OnAppControlResult(app_control_h request,
       static_cast<AppControl::IEventListener*>(user_data);
   app_control_h request_handle = nullptr;
   app_control_clone(&request_handle, request);
-  ev->OnResultReceived(AppControl(request_handle),
-      static_cast<AppControl::Error>(result));
+  try {
+    ev->OnResultReceived(AppControl(request_handle),
+        static_cast<AppControl::Error>(result));
+  } catch(Exception& ex) {
+    LOGE("Exception occurred (%s)", ex.what());
+  }
 }
 
 void Component::Impl::SendAsync(AppControl control,
                                 AppControl::IEventListener* ev) {
-  if (ev == nullptr) {
-    LOGE("Invalid parameter");
-    return;
-  }
+  if (ev == nullptr)
+    THROW(Exception::ErrorCodes::InvalidParameter);
 
   app_control_h handle = control.GetHandle();
-  if (handle == nullptr) {
-    LOGE("Invalid parameter");
-    return;
-  }
+  if (handle == nullptr)
+    THROW(Exception::ErrorCodes::InvalidParameter);
 
   int r = app_control_set_caller_instance_id(handle, inst_id_.c_str());
   if (r != APP_CONTROL_ERROR_NONE) {
     LOGE("Failed to set caller instance(%s)", inst_id_.c_str());
-    return;
+    THROW(Exception::ErrorCodes::InvalidParameter);
   }
 
   r = app_control_send_launch_request_async(handle,
       OnAppControlResult, OnAppControlReply, ev);
   if (r != APP_CONTROL_ERROR_NONE) {
     LOGE("Failed to send launch request async. err(%d)", r);
-    return;
+    THROW(Exception::ErrorCodes::InvalidParameter);
   }
 }
 
 AppControl Component::Impl::Send(AppControl control) {
   app_control_h reply = nullptr;
   app_control_h handle = control.GetHandle();
-  if (handle == nullptr) {
-    LOGE("Invalid parameter");
-    return AppControl(reply);
-  }
+  if (handle == nullptr)
+    THROW(Exception::ErrorCodes::InvalidParameter);
 
   int r = app_control_set_caller_instance_id(handle, inst_id_.c_str());
   if (r != APP_CONTROL_ERROR_NONE) {
     LOGE("Failed to set caller instance(%s)", inst_id_.c_str());
-    return AppControl(reply);
+    THROW(Exception::ErrorCodes::InvalidParameter);
   }
 
   app_control_result_e result;
   r = app_control_send_launch_request_sync(handle, &reply, &result);
   if (r != APP_CONTROL_ERROR_NONE) {
     LOGE("Failed to send launch request sync. err(%d)", r);
-    return AppControl(nullptr);
+    THROW(Exception::ErrorCodes::IOError);
+  }
+
+  try {
+    AppControl control(reply);
+    return control;
+  } catch(Exception& ex) {
+    LOGE("Exception occurred (%s)", ex.what());
+    throw;
   }
-  LOGI("result(%d)", result);
-  return AppControl(reply);
 }
 
 Component::Component(Component::Type type, std::string comp_id,
@@ -320,19 +357,34 @@ Component::Type Component::GetType() {
 }
 
 void Component::RegisterAction(std::string app_control_name) {
-  impl_->RegisterAction(std::move(app_control_name));
+  try {
+    impl_->RegisterAction(std::move(app_control_name));
+  } catch(Exception& ex) {
+    LOGE("Exception occurred (%s)", ex.what());
+    throw;
+  }
 }
 
-void Component::DeregisterAction(std::string app_control_name) {
-  impl_->DeregisterAction(std::move(app_control_name));
+bool Component::DeregisterAction(std::string app_control_name) {
+  return impl_->DeregisterAction(std::move(app_control_name));
 }
 
 void Component::SendAsync(AppControl control, AppControl::IEventListener* ev) {
-  impl_->SendAsync(std::move(control), ev);
+  try {
+    impl_->SendAsync(std::move(control), ev);
+  } catch(Exception& ex) {
+    LOGE("Exception occurred (%s)", ex.what());
+    throw;
+  }
 }
 
 AppControl Component::Send(AppControl control) {
-  return impl_->Send(std::move(control));
+  try {
+    return impl_->Send(std::move(control));
+  } catch(Exception& ex) {
+    LOGE("Exception occurred (%s)", ex.what());
+    throw;
+  }
 }
 
 }  // namespace component_based
index 98be752c972bcd434bc5362c4715e35697e5dbbc..2469014409c1a3bc8156e4ea38b31ed19ae7b891 100644 (file)
@@ -68,7 +68,7 @@ class EXPORT_API Component {
   void Finish();
   Type GetType();
   void RegisterAction(std::string app_control_name);
-  void DeregisterAction(std::string app_control_name);
+  bool DeregisterAction(std::string app_control_name);
   void SendAsync(AppControl control, AppControl::IEventListener* ev);
   AppControl Send(AppControl control);
 
index 026df09eee02f41deb3fdadc9014dac8b59c8ca3..e1d0c3936364af205855fbf4c63e7ba661c4985e 100644 (file)
@@ -66,7 +66,7 @@ class Component::Impl : internal::ComponentManager::IEventListener,
   void OnSuspendedStateChanged(SuspendedState::State state) override;
 
   void RegisterAction(std::string app_control_name);
-  void DeregisterAction(std::string app_control_name);
+  bool DeregisterAction(std::string app_control_name);
 
   const Component::Type& GetType() {
     return type_;
index 5b859e7ac06272f47c456a4cf537cf2b848cc7c2..90c57e1a062d6f5c544ed065fec8f81515181326 100644 (file)
@@ -20,6 +20,7 @@
 #include <memory>
 #include <string>
 
+#include "component_based/common/exception.h"
 #include "component_based/base/component_manager_internal.h"
 #include "component_based/base/dlog_internal.h"
 
@@ -33,6 +34,8 @@ void ComponentManager::RegisterComponent(std::string comp_id,
     appcore_multiwindow_base_class cls =
         appcore_multiwindow_base_class_get_default();
     cls.id = strdup(comp_id.c_str());
+    if (cls.id == nullptr)
+      throw std::bad_alloc();
     cls.data = this;
     cls.create = OnCreateCB;
     cls.terminate = OnTerminateCB;
@@ -61,6 +64,10 @@ void ComponentManager::Start(std::string comp_id, std::string inst_id,
     }
     std::unique_ptr<Component> component = fac_map_[comp_id]->Create(comp_id,
         inst_id);
+    if (component == nullptr || component.get() == nullptr) {
+      LOGE("Fail to create component");
+      return;
+    }
     inst_map_[inst_id] = std::move(component);
     appcore_multiwindow_base_instance_run(comp_id.c_str(), inst_id.c_str(),
         nullptr);
@@ -73,8 +80,12 @@ void ComponentManager::Start(std::string comp_id, std::string inst_id,
 
   app_control_h handle = nullptr;
   app_control_create_event(b, &handle);
-  AppControl control(handle);
-  ev_map_[inst_id]->OnStart(control, restarted);
+  try {
+    AppControl control(handle);
+    ev_map_[inst_id]->OnStart(control, restarted);
+  } catch(Exception& ex) {
+    LOGE("Exception occurred (%s)", ex.what());
+  }
 }
 
 void ComponentManager::Resume(std::string inst_id) {
@@ -129,23 +140,24 @@ void ComponentManager::ExitAll() {
   }
 }
 
-void ComponentManager::Bind(std::string inst_id, std::unique_ptr<IWindow> win) {
+bool ComponentManager::Bind(std::string inst_id, std::unique_ptr<IWindow> win) {
   appcore_multiwindow_base_instance_h context =
       appcore_multiwindow_base_instance_find(inst_id.c_str());
   if (!context) {
     LOGE("Failed to find instance(%s)", inst_id.c_str());
-    return;
+    return false;
   }
 
   win_map_[inst_id] = std::move(win);
   Ecore_Wl2_Window* wl_win = GetWl2Window(inst_id);
   if (!wl_win) {
     LOGE("Failed to get wayland window(%s)", inst_id.c_str());
-    return;
+    return false;
   }
 
   appcore_multiwindow_base_window_bind(context, wl_win);
   LOGI("Bind instance(%s)", inst_id.c_str());
+  return true;
 }
 
 void ComponentManager::Unbind(std::string inst_id) {
index 063e340fe7ec12380389c88878686ee27eca9fc3..df14638b8c645741701dfb306c118c5be550a2d7 100644 (file)
@@ -64,7 +64,7 @@ class ComponentManager {
 
   void Exit(std::string inst_id);
   void ExitAll();
-  void Bind(std::string inst_id, std::unique_ptr<IWindow> win);
+  bool Bind(std::string inst_id, std::unique_ptr<IWindow> win);
   void Unbind(std::string inst_id);
   std::string GetInstanceID(int win_id);
   const IWindow* GetWindow(std::string inst_id);
diff --git a/component_based/base/exception.h b/component_based/base/exception.h
deleted file mode 100644 (file)
index 31a3745..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef COMPONENT_BASED_BASE_EXCEPTION_H_
-#define COMPONENT_BASED_BASE_EXCEPTION_H_
-
-#include <app_types.h>
-
-#include <exception>
-#include <string>
-
-#define THROW(error_code) throw Exception(error_code, __FILE__, __LINE__)
-
-namespace component_based {
-
-class Exception : public std::exception {
- public:
-  explicit Exception(int error_code, std::string file = __FILE__,
-      int line = __LINE__ ) {
-    error_code_ = error_code;
-    message_ = file.substr(file.find_last_of("/") + 1) + ":"
-        + std::to_string(line) + GetErrorString(error_code);
-  }
-  virtual ~Exception() {}
-  virtual const char *what(void) const noexcept {
-    return message_.c_str();
-  }
-  int GetErrorCode() {
-    return error_code_;
-  }
-
- private:
-  int error_code_;
-  std::string message_;
-  std::string GetErrorString(int error_code) {
-    switch (error_code) {
-    case APP_ERROR_INVALID_PARAMETER:
-      return ": INVALID_PARAMETER";
-    case APP_ERROR_OUT_OF_MEMORY:
-      return ": OUT_OF_MEMORY";
-    case APP_ERROR_INVALID_CONTEXT:
-      return ": INVALID_CONTEXT";
-    case APP_ERROR_NO_SUCH_FILE:
-      return ": NO_SUCH_FILE";
-    case APP_ERROR_NOT_SUPPORTED:
-      return ": NOT_SUPPORTED";
-    case APP_ERROR_ALREADY_RUNNING:
-      return ": ALREADY_RUNNING";
-    case APP_ERROR_PERMISSION_DENIED:
-      return ": PERMISSION_DENIED";
-    default:
-      return "";
-    }
-  }
-};
-
-}  // namespace component_based
-
-#endif  // COMPONENT_BASED_BASE_EXCEPTION_H_
index c3ee15b38719bcf31508f18a382471c6e3d232b8..3d52acc518c21ba946af04e3781a929d6f09d431 100644 (file)
@@ -35,7 +35,8 @@ class EXPORT_API FrameComponent : public Component {
     std::unique_ptr<Component> Create(std::string comp_id,
                                       std::string inst_id) override {
       return std::unique_ptr<Component>(
-          new FrameComponent(std::move(comp_id), std::move(inst_id)));
+          new (std::nothrow) FrameComponent(
+            std::move(comp_id), std::move(inst_id)));
     }
   };
 
index a9a39dfb053f9bd37896e4a151ebe79c3e139d52..fbf6b729b44a2b0fb465fef6569802700652e90d 100644 (file)
@@ -34,7 +34,8 @@ class EXPORT_API ServiceComponent : public Component {
     std::unique_ptr<Component> Create(std::string comp_id,
                                       std::string inst_id) override {
       return std::unique_ptr<Component>(
-          new ServiceComponent(std::move(comp_id), std::move(inst_id)));
+          new (std::nothrow) ServiceComponent(
+            std::move(comp_id), std::move(inst_id)));
     }
   };
 
diff --git a/component_based/common/exception.h b/component_based/common/exception.h
new file mode 100644 (file)
index 0000000..2058d99
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef COMPONENT_BASED_COMMON_EXCEPTION_H_
+#define COMPONENT_BASED_COMMON_EXCEPTION_H_
+
+#include <exception>
+#include <string>
+
+#define THROW(error_code) throw Exception(error_code, __FILE__, __LINE__)
+
+namespace component_based {
+
+class Exception : public std::exception {
+ public:
+  enum class ErrorCodes {
+    InvalidParameter,
+    OutOfMemory,
+    IOError,
+  };
+  explicit Exception(ErrorCodes error_code, std::string file = __FILE__,
+      int line = __LINE__ ) {
+    error_code_ = error_code;
+    message_ = file.substr(file.find_last_of("/") + 1) + ":"
+        + std::to_string(line) + GetErrorString(error_code);
+  }
+  virtual ~Exception() {}
+  virtual const char *what(void) const noexcept {
+    return message_.c_str();
+  }
+  ErrorCodes GetErrorCode() {
+    return error_code_;
+  }
+
+ private:
+  ErrorCodes error_code_;
+  std::string message_;
+  std::string GetErrorString(ErrorCodes error_code) {
+    switch (error_code) {
+    case ErrorCodes::InvalidParameter:
+      return ": INVALID_PARAMETER";
+    case ErrorCodes::OutOfMemory:
+      return ": OUT_OF_MEMORY";
+    case ErrorCodes::IOError:
+      return ": ERROR_IO_ERROR";
+    default:
+      return "";
+    }
+  }
+};
+
+}  // namespace component_based
+
+#endif  // COMPONENT_BASED_COMMON_EXCEPTION_H_
index a2a074aaab02bcd5eec4826a8897c7e14ee9bb1e..ae6e3d7618825011e8cc8a31ce0d549faca83e2a 100644 (file)
@@ -26,6 +26,7 @@
 #include "component_based/efl_base/api/service_component.h"
 #include "component_based/efl_base/api/component_based_app.h"
 
+#include "component_based/common/exception.h"
 #include "component_based/efl_base/application.h"
 #include "component_based/efl_base/elm_window.h"
 
@@ -113,7 +114,7 @@ class StubApplication : public component_based::Application {
   std::map<std::string, std::unique_ptr<component_based::Component::Factory>>
   OnCreate() override {
     std::map<std::string, std::unique_ptr<component_based::Component::Factory>> facs;
-    component_class_h h = nullptr;;
+    component_class_h h = nullptr;
     if (cb_.create)
       h = cb_.create(user_data_);
 
@@ -150,8 +151,8 @@ class StubFrameComponent : public component_based::FrameComponent {
     std::unique_ptr<component_based::Component> Create(std::string comp_id,
         std::string inst_id) override {
       return std::unique_ptr<component_based::Component>(
-          new StubFrameComponent(std::move(comp_id), std::move(inst_id),
-              cb_, user_data_));
+          new (std::nothrow) StubFrameComponent(
+            std::move(comp_id), std::move(inst_id), cb_, user_data_));
     }
 
    private:
@@ -291,8 +292,8 @@ class StubServiceComponent : public component_based::ServiceComponent {
     std::unique_ptr<component_based::Component> Create(std::string comp_id,
         std::string inst_id) override {
       return std::unique_ptr<component_based::Component>(
-          new StubServiceComponent(std::move(comp_id), std::move(inst_id),
-              cb_, user_data_));
+          new (std::nothrow) StubServiceComponent(std::move(comp_id),
+              std::move(inst_id), cb_, user_data_));
     }
 
    private:
@@ -441,7 +442,7 @@ component_based_app_add_frame_component(
 
   ::ComponentClass* handle;
   if (comp_class == nullptr) {
-    handle = new ::ComponentClass();
+    handle = new (std::nothrow) ::ComponentClass();
     if (handle == nullptr) {
       LOGE("Out of memory");
       set_last_result(APP_ERROR_OUT_OF_MEMORY);
@@ -556,7 +557,12 @@ extern "C" EXPORT_API int component_register_action(component_h h,
 
   component_based::Component* component =
       static_cast<component_based::Component*>(h);
-  component->RegisterAction(action);
+  try {
+    component->RegisterAction(action);
+  } catch (component_based::Exception& ex) {
+    LOGE("Exception occurred (%s)", ex.what());
+    return COMPONENT_ERROR_INVALID_CONTEXT;
+  }
 
   return COMPONENT_ERROR_NONE;
 }
@@ -570,7 +576,10 @@ extern "C" EXPORT_API int component_deregister_action(
 
   component_based::Component* component =
       static_cast<component_based::Component*>(h);
-  component->DeregisterAction(action);
+  if (!component->DeregisterAction(action)) {
+    LOGE("Deregister fail");
+    return COMPONENT_ERROR_INVALID_PARAMETER;
+  }
 
   return COMPONENT_ERROR_NONE;
 }
@@ -630,7 +639,7 @@ static int __app_control_send_launch_request_sync(
 
   r = app_control_send_launch_request_sync(app_control, reply, result);
   if (r != APP_CONTROL_ERROR_NONE) {
-    LOGE("Failed to send launch request async. error(%d)", r);
+    LOGE("Failed to send launch request sync. error(%d)", r);
     return __app_control_error_convert(r);
   }
 
index 20568e285c08a0a85a1d1baa791583202c254ebc..fbc2f961e7d76de4eda72ce5fc627b986aee0771 100644 (file)
@@ -26,6 +26,17 @@ class ComponentTest : public ::testing::Test {
   void TearDown() override {}
 };
 
+class TestListener : public component_based::AppControl::IEventListener {
+ public:
+  void OnResultReceived(component_based::AppControl request,
+                                component_based::AppControl::Error error) {
+  }
+  void OnReplyReceived(component_based::AppControl request,
+      component_based::AppControl reply,
+      component_based::AppControl::Result result) {
+  }
+};
+
 int __fake_app_get_display_state(app_display_state_e* state) {
   *state = APP_DISPLAY_STATE_ON;
   return 0;
@@ -145,8 +156,9 @@ TEST_F(ComponentTest, TestComponentClass) {
   builder->SetComponentID("ElmFrame");
 
   component_based::AppControl ctrl = builder->Build();
-  component_based::AppControl::IEventListener* ev = nullptr;
-  fc->SendAsync(ctrl, ev);
+  std::unique_ptr<TestListener> listener =
+      std::unique_ptr<TestListener>(new TestListener());
+  fc->SendAsync(ctrl, listener.get());
 
   fc->Send(ctrl);
 }