]> granicus.if.org Git - icinga2/commitdiff
Improve error handling for Icinga Studio
authorGunnar Beutner <gunnar@beutner.name>
Wed, 30 Sep 2015 07:40:29 +0000 (09:40 +0200)
committerGunnar Beutner <gunnar@beutner.name>
Wed, 30 Sep 2015 07:40:29 +0000 (09:40 +0200)
refs #10042

icinga-studio/mainform.cpp
icinga-studio/mainform.hpp

index 3d1437cda3d6bfe1392c4a989c938058a9eeb12f..9075b35e8ecb5e3380c463481b2328014015f847 100644 (file)
@@ -22,6 +22,7 @@
 #include <boost/algorithm/string/split.hpp>
 #include <boost/algorithm/string/classification.hpp>
 #include <boost/foreach.hpp>
+#include <wx/msgdlg.h>
 
 using namespace icinga;
 
@@ -39,7 +40,7 @@ MainForm::MainForm(wxWindow *parent, const Url::Ptr& url)
                port = "5665";
 
        m_ApiClient = new ApiClient(url->GetHost(), port, url->GetUsername(), url->GetPassword());
-       m_ApiClient->GetTypes(boost::bind(&MainForm::TypesCompletionHandler, this, _2, true));
+       m_ApiClient->GetTypes(boost::bind(&MainForm::TypesCompletionHandler, this, _1, _2, true));
 
        std::string title = url->Format() + " - Icinga Studio";
        SetTitle(title);
@@ -47,14 +48,26 @@ MainForm::MainForm(wxWindow *parent, const Url::Ptr& url)
        m_ObjectsList->InsertColumn(0, "Name", 0, 300);
 }
 
-void MainForm::TypesCompletionHandler(const std::vector<ApiType::Ptr>& types, bool forward)
+void MainForm::TypesCompletionHandler(boost::exception_ptr eptr, const std::vector<ApiType::Ptr>& types, bool forward)
 {
        if (forward) {
-               CallAfter(boost::bind(&MainForm::TypesCompletionHandler, this, types, false));
+               CallAfter(boost::bind(&MainForm::TypesCompletionHandler, this, eptr, types, false));
                return;
        }
 
        m_TypesTree->DeleteAllItems();
+
+       if (eptr) {
+               try {
+                       boost::rethrow_exception(eptr);
+               } catch (const std::exception& ex) {
+                       std::string message = "HTTP query failed: " + std::string(ex.what());
+                       wxMessageBox(message, "Icinga Studio", wxOK | wxCENTRE | wxICON_ERROR, this);
+                       Close();
+                       return;
+               }
+       }
+
        wxTreeItemId rootNode = m_TypesTree->AddRoot("root");
 
        bool all = false;
@@ -101,25 +114,37 @@ void MainForm::OnTypeSelected(wxTreeEvent& event)
        std::vector<String> attrs;
        attrs.push_back(type->Name.ToLower() + ".__name");
 
-       m_ApiClient->GetObjects(type->PluralName, boost::bind(&MainForm::ObjectsCompletionHandler, this, _2, true),
+       m_ApiClient->GetObjects(type->PluralName, boost::bind(&MainForm::ObjectsCompletionHandler, this, _1, _2, true),
            std::vector<String>(), attrs);
 }
 
-void MainForm::ObjectsCompletionHandler(const std::vector<ApiObject::Ptr>& objects, bool forward)
+void MainForm::ObjectsCompletionHandler(boost::exception_ptr eptr, const std::vector<ApiObject::Ptr>& objects, bool forward)
 {
        if (forward) {
-               CallAfter(boost::bind(&MainForm::ObjectsCompletionHandler, this, objects, false));
+               CallAfter(boost::bind(&MainForm::ObjectsCompletionHandler, this, eptr, objects, false));
                return;
        }
 
+       m_ObjectsList->DeleteAllItems();
+       m_PropertyGrid->Clear();
+
+       if (eptr) {
+
+               try {
+                       boost::rethrow_exception(eptr);
+               } catch (const std::exception& ex) {
+                       std::string message = "HTTP query failed: " + std::string(ex.what());
+                       wxMessageBox(message, "Icinga Studio", wxOK | wxCENTRE | wxICON_ERROR, this);
+                       return;
+               }
+       }
+
        wxTreeItemId selectedId = m_TypesTree->GetSelection();
        wxString typeName = m_TypesTree->GetItemText(selectedId);
        ApiType::Ptr type = m_Types[typeName.ToStdString()];
 
        String nameAttr = type->Name.ToLower() + ".__name";
 
-       m_ObjectsList->DeleteAllItems();
-
        BOOST_FOREACH(const ApiObject::Ptr& object, objects) {
                std::map<String, Value>::const_iterator it = object->Attrs.find(nameAttr);
                if (it == object->Attrs.end())
@@ -150,7 +175,7 @@ void MainForm::OnObjectSelected(wxListEvent& event)
        std::vector<String> names;
        names.push_back(objectName);
 
-       m_ApiClient->GetObjects(type->PluralName, boost::bind(&MainForm::ObjectDetailsCompletionHandler, this, _2, true), names);
+       m_ApiClient->GetObjects(type->PluralName, boost::bind(&MainForm::ObjectDetailsCompletionHandler, this, _1, _2, true), names);
 }
 
 wxPGProperty *MainForm::ValueToProperty(const String& name, const Value& value)
@@ -190,33 +215,55 @@ wxPGProperty *MainForm::ValueToProperty(const String& name, const Value& value)
        }
 }
 
-void MainForm::ObjectDetailsCompletionHandler(const std::vector<ApiObject::Ptr>& objects, bool forward)
+void MainForm::ObjectDetailsCompletionHandler(boost::exception_ptr eptr, const std::vector<ApiObject::Ptr>& objects, bool forward)
 {
        if (forward) {
-               CallAfter(boost::bind(&MainForm::ObjectDetailsCompletionHandler, this, objects, false));
+               CallAfter(boost::bind(&MainForm::ObjectDetailsCompletionHandler, this, eptr, objects, false));
                return;
        }
 
+       m_PropertyGrid->Clear();
+
+       if (eptr) {
+               try {
+                       boost::rethrow_exception(eptr);
+               } catch (const std::exception& ex) {
+                       std::string message = "HTTP query failed: " + std::string(ex.what());
+                       wxMessageBox(message, "Icinga Studio", wxOK | wxCENTRE | wxICON_ERROR, this);
+               }
+       }
+
        wxTreeItemId selectedId = m_TypesTree->GetSelection();
        wxString typeName = m_TypesTree->GetItemText(selectedId);
        ApiType::Ptr type = m_Types[typeName.ToStdString()];
 
        String nameAttr = type->Name.ToLower() + ".__name";
 
-       m_PropertyGrid->Clear();
-       
        if (objects.empty())
                return;
 
        ApiObject::Ptr object = objects[0];
 
+       std::map<String, wxStringProperty *> parents;
+
        typedef std::pair<String, Value> kv_pair;
        BOOST_FOREACH(const kv_pair& kv, object->Attrs) {
                std::vector<String> tokens;
                boost::algorithm::split(tokens, kv.first, boost::is_any_of("."));
 
+               std::map<String, wxStringProperty *>::const_iterator it = parents.find(tokens[0]);
+
+               wxStringProperty *parent;
+
+               if (it == parents.end()) {
+                       parent = new wxStringProperty(tokens[0].GetData(), wxPG_LABEL, "<object>");
+                       m_PropertyGrid->Append(parent);
+                       parents[tokens[0]] = parent;
+               } else
+                       parent = it->second;
+
                wxPGProperty *prop = ValueToProperty(tokens[1], kv.second);
-               m_PropertyGrid->Append(prop);
+               parent->AppendChild(prop);
                m_PropertyGrid->SetPropertyReadOnly(prop);
        }
 }
index 2837e7f0bcc1e9b92fcd4cb01e86d4d82b747c80..2e244a71f250dba21042d68a020b00277de4b0b7 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "icinga-studio/apiclient.hpp"
 #include "remote/url.hpp"
+#include "base/exception.hpp"
 #include "icinga-studio/forms.h"
 
 namespace icinga
@@ -41,9 +42,9 @@ private:
        ApiClient::Ptr m_ApiClient;
        std::map<String, ApiType::Ptr> m_Types;
 
-       void TypesCompletionHandler(const std::vector<ApiType::Ptr>& types, bool forward);
-       void ObjectsCompletionHandler(const std::vector<ApiObject::Ptr>& objects, bool forward);
-       void ObjectDetailsCompletionHandler(const std::vector<ApiObject::Ptr>& objects, bool forward);
+       void TypesCompletionHandler(boost::exception_ptr eptr, const std::vector<ApiType::Ptr>& types, bool forward);
+       void ObjectsCompletionHandler(boost::exception_ptr eptr, const std::vector<ApiObject::Ptr>& objects, bool forward);
+       void ObjectDetailsCompletionHandler(boost::exception_ptr eptr, const std::vector<ApiObject::Ptr>& objects, bool forward);
 
        wxPGProperty *ValueToProperty(const String& name, const Value& value);
 };