From 335ab739bd5f74b99203c17fead02970664d293f Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Mon, 6 Nov 2023 16:41:33 +0100
Subject: [PATCH] Throw proper exception if skill is not found when
 constructing subskill proxy

---
 .../RobotAPI/libraries/skills/core/Skill.cpp  |  4 +--
 .../libraries/skills/core/SkillProxy.cpp      | 16 +++++++++---
 .../libraries/skills/core/error/Exception.h   | 26 ++++++++++++-------
 3 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/source/RobotAPI/libraries/skills/core/Skill.cpp b/source/RobotAPI/libraries/skills/core/Skill.cpp
index 7d94de3e9..0b7a32df2 100644
--- a/source/RobotAPI/libraries/skills/core/Skill.cpp
+++ b/source/RobotAPI/libraries/skills/core/Skill.cpp
@@ -245,7 +245,7 @@ namespace armarx
                     std::string("The skill '" + getSkillId().toString() + "' was asked to stop.");
                 message += abortedMessage.empty() ? "" : " Additional message: " + abortedMessage;
 
-                throw error::SkillAbortedException(message);
+                throw error::SkillAbortedException(__PRETTY_FUNCTION__, message);
                 return;
             }
 
@@ -256,7 +256,7 @@ namespace armarx
                 message += abortedMessage.empty() ? "" : " Additional message: " + abortedMessage;
 
                 ARMARX_WARNING << message;
-                throw error::SkillFailedException(message);
+                throw error::SkillFailedException(__PRETTY_FUNCTION__, message);
             }
         }
 
diff --git a/source/RobotAPI/libraries/skills/core/SkillProxy.cpp b/source/RobotAPI/libraries/skills/core/SkillProxy.cpp
index f73c43dfd..ea4fc4d1a 100644
--- a/source/RobotAPI/libraries/skills/core/SkillProxy.cpp
+++ b/source/RobotAPI/libraries/skills/core/SkillProxy.cpp
@@ -12,9 +12,19 @@ namespace armarx
             manager(manager)
         {
             ARMARX_CHECK_NOT_NULL(manager);
-            skillDescription = SkillDescription::FromIce(
-                manager->getSkillDescription(skillId.toManagerIce()).value());
-            ARMARX_CHECK(skillDescription.skillId.isFullySpecified());
+            IceUtil::Optional<manager::dto::SkillDescription> description =
+                manager->getSkillDescription(skillId.toManagerIce());
+            if (description)
+            {
+                skillDescription = SkillDescription::FromIce(description.value());
+                ARMARX_CHECK(skillDescription.skillId.isFullySpecified());
+            }
+            else
+            {
+                std::stringstream reason;
+                reason << "No skill with ID " << skillId << " found";
+                throw error::SkillNotFoundException(__PRETTY_FUNCTION__, reason.str());
+            }
         }
 
         SkillProxy::SkillProxy(const manager::dti::SkillManagerInterfacePrx& manager,
diff --git a/source/RobotAPI/libraries/skills/core/error/Exception.h b/source/RobotAPI/libraries/skills/core/error/Exception.h
index 5e10baed1..9e01205b2 100644
--- a/source/RobotAPI/libraries/skills/core/error/Exception.h
+++ b/source/RobotAPI/libraries/skills/core/error/Exception.h
@@ -48,32 +48,38 @@ namespace armarx::skills::error
         }
     };
 
-    class SkillAbortedException : public armarx::LocalException
+    /**
+     * @brief Indicates that a skill was not found, e.g., by the skill manager.
+     */
+    class SkillNotFoundException : public SkillException
     {
     public:
-        SkillAbortedException() = delete;
+        SkillNotFoundException() = delete;
 
-        SkillAbortedException(const std::string& reason) : LocalException(reason)
+        SkillNotFoundException(const std::string& prettymethod, const std::string& reason) :
+            SkillException(prettymethod, reason)
         {
         }
+    };
+
+    class SkillAbortedException : public SkillException
+    {
+    public:
+        SkillAbortedException() = delete;
 
         SkillAbortedException(const std::string& prettymethod, const std::string& reason) :
-            LocalException(prettymethod + ": " + reason + ".")
+            SkillException(prettymethod, reason)
         {
         }
     };
 
-    class SkillFailedException : public armarx::LocalException
+    class SkillFailedException : public SkillException
     {
     public:
         SkillFailedException() = delete;
 
-        SkillFailedException(const std::string& reason) : LocalException(reason)
-        {
-        }
-
         SkillFailedException(const std::string& prettymethod, const std::string& reason) :
-            LocalException(prettymethod + ": " + reason + ".")
+            SkillException(prettymethod, reason)
         {
         }
     };
-- 
GitLab