summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Qiu <zqiu@google.com>2015-11-19 13:13:25 -0800
committerPeter Qiu <zqiu@google.com>2015-11-20 09:00:12 -0800
commit69d252180b766970ccbfeeb7af00973d3331d086 (patch)
tree3fc85fc237bc1e5ee4b725e9be265f2e55ea5ffb
parent00029783fc5a927dd0cddc03bdcd8e760655ce46 (diff)
downloadapmanager-69d252180b766970ccbfeeb7af00973d3331d086.tar.gz
Add support for generic internal error reporting
Currently, we're using brillo::Error for internal error reporting. However, brillo::Error is more tailored for D-Bus. Instead, implement a new Error class (trimmed down version of shill::Error) for internal error reporting, and provide functions for converting it to RPC specific error object. Bug: None TEST=Run newly added unit tests Change-Id: I2b518fae6eccb8dc9f9f0e96b941289c3846a9af
-rw-r--r--Android.mk2
-rw-r--r--apmanager.gyp2
-rw-r--r--error.cc86
-rw-r--r--error.h84
-rw-r--r--error_unittest.cc88
5 files changed, 262 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
index d2d0d00..c13c1ae 100644
--- a/Android.mk
+++ b/Android.mk
@@ -76,6 +76,7 @@ LOCAL_SRC_FILES := \
device_info.cc \
dhcp_server.cc \
dhcp_server_factory.cc \
+ error.cc \
event_dispatcher.cc \
file_writer.cc \
firewall_manager.cc \
@@ -109,6 +110,7 @@ LOCAL_SRC_FILES := \
device_info_unittest.cc \
device_unittest.cc \
dhcp_server_unittest.cc \
+ error_unittest.cc \
fake_device_adaptor.cc \
hostapd_monitor_unittest.cc \
manager_unittest.cc \
diff --git a/apmanager.gyp b/apmanager.gyp
index 755e63f..4ce5251 100644
--- a/apmanager.gyp
+++ b/apmanager.gyp
@@ -84,6 +84,7 @@
'device_info.cc',
'dhcp_server.cc',
'dhcp_server_factory.cc',
+ 'error.cc',
'event_dispatcher.cc',
'file_writer.cc',
'firewall_manager.cc',
@@ -145,6 +146,7 @@
'device_info_unittest.cc',
'device_unittest.cc',
'dhcp_server_unittest.cc',
+ 'error_unittest.cc',
'fake_device_adaptor.cc',
'hostapd_monitor_unittest.cc',
'manager_unittest.cc',
diff --git a/error.cc b/error.cc
new file mode 100644
index 0000000..6745efa
--- /dev/null
+++ b/error.cc
@@ -0,0 +1,86 @@
+//
+// Copyright (C) 2012 The Android Open Source Project
+//
+// 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.
+//
+
+#include "apmanager/error.h"
+
+#include <base/files/file_path.h>
+#include <base/logging.h>
+#include <brillo/errors/error.h>
+#include <brillo/errors/error_codes.h>
+
+#if defined(__ANDROID__)
+#include <dbus/service_constants.h>
+#else
+#include <chromeos/dbus/service_constants.h>
+#endif // __ANDROID__
+
+using std::string;
+
+namespace apmanager {
+
+Error::Error() : type_(kSuccess) {}
+
+Error::~Error() {}
+
+void Error::Populate(Type type,
+ const string& message,
+ const tracked_objects::Location& location) {
+ CHECK(type < kNumErrors) << "Error type out of range: " << type;
+ type_ = type;
+ message_ = message;
+ location_ = location;
+}
+
+void Error::Reset() {
+ type_ = kSuccess;
+ message_ = "";
+ location_ = tracked_objects::Location();
+}
+
+bool Error::ToDBusError(brillo::ErrorPtr* error) const {
+ if (IsSuccess()) {
+ return false;
+ }
+
+ string error_code = kErrorInternalError;
+ if (type_ == kInvalidArguments) {
+ error_code = kErrorInvalidArguments;
+ } else if (type_ == kInvalidConfiguration) {
+ error_code = kErrorInvalidConfiguration;
+ }
+
+ brillo::Error::AddTo(error,
+ location_,
+ brillo::errors::dbus::kDomain,
+ error_code,
+ message_);
+ return true;
+}
+
+// static
+void Error::PopulateAndLog(Error* error,
+ Type type,
+ const string& message,
+ const tracked_objects::Location& from_here) {
+ string file_name = base::FilePath(from_here.file_name()).BaseName().value();
+ LOG(ERROR) << "[" << file_name << "("
+ << from_here.line_number() << ")]: "<< message;
+ if (error) {
+ error->Populate(type, message, from_here);
+ }
+}
+
+} // namespace apmanager
diff --git a/error.h b/error.h
new file mode 100644
index 0000000..304b25d
--- /dev/null
+++ b/error.h
@@ -0,0 +1,84 @@
+//
+// Copyright (C) 2015 The Android Open Source Project
+//
+// 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 APMANAGER_ERROR_H_
+#define APMANAGER_ERROR_H_
+
+#include <memory>
+#include <string>
+
+#include <base/location.h>
+#include <base/macros.h>
+
+namespace brillo {
+class Error;
+using ErrorPtr = std::unique_ptr<Error>;
+} // namespace brillo
+
+namespace apmanager {
+
+class Error {
+ public:
+ enum Type {
+ kSuccess = 0, // No error.
+ kOperationInProgress,
+ kInternalError,
+ kInvalidArguments,
+ kInvalidConfiguration,
+ kNumErrors
+ };
+
+ Error();
+ ~Error();
+
+ void Populate(Type type,
+ const std::string& message,
+ const tracked_objects::Location& location);
+
+ void Reset();
+
+ Type type() const { return type_; }
+ const std::string& message() const { return message_; }
+
+ bool IsSuccess() const { return type_ == kSuccess; }
+ bool IsFailure() const { return !IsSuccess() && !IsOngoing(); }
+ bool IsOngoing() const { return type_ == kOperationInProgress; }
+
+ // Log an error message from |from_here|. If |error| is non-NULL, also
+ // populate it.
+ static void PopulateAndLog(Error* error,
+ Type type,
+ const std::string& message,
+ const tracked_objects::Location& from_here);
+
+ // TODO(zqiu): put this under a compiler flag (e.g. __DBUS__).
+ // Sets the D-Bus error and returns true if Error represents failure.
+ // Leaves error unchanged, and returns false otherwise.
+ bool ToDBusError(brillo::ErrorPtr* error) const;
+
+ private:
+ friend class ErrorTest;
+
+ Type type_;
+ std::string message_;
+ tracked_objects::Location location_;
+
+ DISALLOW_COPY_AND_ASSIGN(Error);
+};
+
+} // namespace apmanager
+
+#endif // APMANAGER_ERROR_H_
diff --git a/error_unittest.cc b/error_unittest.cc
new file mode 100644
index 0000000..7e51c08
--- /dev/null
+++ b/error_unittest.cc
@@ -0,0 +1,88 @@
+//
+// Copyright (C) 2011 The Android Open Source Project
+//
+// 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.
+//
+
+#include "apmanager/error.h"
+
+#include <string>
+
+#include <brillo/errors/error.h>
+#include <brillo/errors/error_codes.h>
+#include <gtest/gtest.h>
+
+#if defined(__ANDROID__)
+#include <dbus/service_constants.h>
+#else
+#include <chromeos/dbus/service_constants.h>
+#endif // __ANDROID__
+
+using std::string;
+using testing::Test;
+
+namespace apmanager {
+
+class ErrorTest : public Test {
+ public:
+ ErrorTest() {}
+
+ void PopulateError(Error* error, Error::Type type) {
+ error->type_ = type;
+ }
+
+ void PopulateError(Error* error, Error::Type type, string message) {
+ error->type_ = type;
+ error->message_ = message;
+ }
+
+ void VerifyDBusError(Error::Type type, const string& expected_error_code) {
+ static const std::string kMessage = "Test error message";
+ Error e;
+ PopulateError(&e, type, kMessage);
+ brillo::ErrorPtr dbus_error;
+ EXPECT_TRUE(e.ToDBusError(&dbus_error));
+ EXPECT_NE(nullptr, dbus_error.get());
+ EXPECT_EQ(brillo::errors::dbus::kDomain, dbus_error->GetDomain());
+ EXPECT_EQ(expected_error_code, dbus_error->GetCode());
+ EXPECT_EQ(kMessage, dbus_error->GetMessage());
+ }
+};
+
+TEST_F(ErrorTest, Constructor) {
+ Error e;
+ EXPECT_EQ(Error::kSuccess, e.type());
+}
+
+TEST_F(ErrorTest, Reset) {
+ Error e;
+ PopulateError(&e, Error::kInternalError);
+ EXPECT_TRUE(e.IsFailure());
+ e.Reset();
+ EXPECT_TRUE(e.IsSuccess());
+}
+
+TEST_F(ErrorTest, ToDBusError) {
+ brillo::ErrorPtr dbus_error;
+
+ // No error.
+ EXPECT_EQ(nullptr, dbus_error.get());
+ EXPECT_FALSE(Error().ToDBusError(&dbus_error));
+ EXPECT_EQ(nullptr, dbus_error.get());
+
+ VerifyDBusError(Error::kInternalError, kErrorInternalError);
+ VerifyDBusError(Error::kInvalidArguments, kErrorInvalidArguments);
+ VerifyDBusError(Error::kInvalidConfiguration, kErrorInvalidConfiguration);
+}
+
+} // namespace shill