error handling for devices and deviceclasses resource

pull/135/head
Simon Stürz 2015-09-27 12:53:11 +02:00 committed by Michael Zanetti
parent e070138e4b
commit 8cd6866ffb
8 changed files with 94 additions and 29 deletions

View File

@ -2,7 +2,7 @@
GUH_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"')
# define protocol versions
JSON_PROTOCOL_VERSION=28
JSON_PROTOCOL_VERSION=29
REST_API_VERSION=1
DEFINES += GUH_VERSION_STRING=\\\"$${GUH_VERSION_STRING}\\\" \

View File

@ -61,6 +61,8 @@
No Error. Everything went fine.
\value DeviceErrorPluginNotFound
Couldn't find the Plugin for the given id.
\value DeviceErrorVendorNotFound
Couldn't find the Vendor for the given id.
\value DeviceErrorDeviceNotFound
Couldn't find a \l{Device} for the given id.
\value DeviceErrorDeviceClassNotFound

View File

@ -64,6 +64,7 @@ public:
enum DeviceError {
DeviceErrorNoError,
DeviceErrorPluginNotFound,
DeviceErrorVendorNotFound,
DeviceErrorDeviceNotFound,
DeviceErrorDeviceClassNotFound,
DeviceErrorActionTypeNotFound,

View File

@ -47,12 +47,12 @@ HttpReply *DeviceClassesResource::proccessRequest(const HttpRequest &request, co
DeviceClassId deviceClassId = DeviceClassId(urlTokens.at(3));
if (deviceClassId.isNull()) {
qCWarning(dcRest) << "Could not parse DeviceClassId:" << urlTokens.at(3);
return createErrorReply(HttpReply::BadRequest);
return createDeviceErrorReply(HttpReply::BadRequest, DeviceManager::DeviceErrorDeviceClassNotFound);
}
m_deviceClass = GuhCore::instance()->findDeviceClass(deviceClassId);
if (!m_deviceClass.isValid()) {
qCWarning(dcRest) << "DeviceClassId" << deviceClassId.toString() << "not found";
return createErrorReply(HttpReply::NotFound);
return createDeviceErrorReply(HttpReply::NotFound, DeviceManager::DeviceErrorDeviceClassNotFound);
}
}
@ -81,7 +81,7 @@ HttpReply *DeviceClassesResource::proccessGetRequest(const HttpRequest &request,
vendorId = VendorId(request.urlQuery().queryItemValue("vendorId"));
if (vendorId.isNull()) {
qCWarning(dcRest) << "Could not parse VendorId:" << request.urlQuery().queryItemValue("vendorId");
return createErrorReply(HttpReply::BadRequest);
return createDeviceErrorReply(HttpReply::BadRequest, DeviceManager::DeviceErrorVendorNotFound);
}
}
}
@ -101,7 +101,7 @@ HttpReply *DeviceClassesResource::proccessGetRequest(const HttpRequest &request,
ActionTypeId actionTypeId = ActionTypeId(urlTokens.at(5));
if (actionTypeId.isNull()) {
qCWarning(dcRest) << "Could not parse ActionTypeId:" << urlTokens.at(5);
return createErrorReply(HttpReply::BadRequest);
return createDeviceErrorReply(HttpReply::BadRequest, DeviceManager::DeviceErrorActionTypeNotFound);
}
return getActionType(actionTypeId);
}
@ -115,7 +115,7 @@ HttpReply *DeviceClassesResource::proccessGetRequest(const HttpRequest &request,
StateTypeId stateTypeId = StateTypeId(urlTokens.at(5));
if (stateTypeId.isNull()) {
qCWarning(dcRest) << "Could not parse StateTypeId:" << urlTokens.at(5);
return createErrorReply(HttpReply::BadRequest);
return createDeviceErrorReply(HttpReply::BadRequest, DeviceManager::DeviceErrorStateTypeNotFound);
}
return getStateType(stateTypeId);
}
@ -129,7 +129,7 @@ HttpReply *DeviceClassesResource::proccessGetRequest(const HttpRequest &request,
EventTypeId eventTypeId = EventTypeId(urlTokens.at(5));
if (eventTypeId.isNull()) {
qCWarning(dcRest) << "Could not parse EventTypeId:" << urlTokens.at(5);
return createErrorReply(HttpReply::BadRequest);
return createDeviceErrorReply(HttpReply::BadRequest, DeviceManager::DeviceErrorEventTypeNotFound);
}
return getEventType(eventTypeId);
}
@ -182,7 +182,7 @@ HttpReply *DeviceClassesResource::getActionType(const ActionTypeId &actionTypeId
return reply;
}
}
return createErrorReply(HttpReply::NotFound);
return createDeviceErrorReply(HttpReply::NotFound, DeviceManager::DeviceErrorActionTypeNotFound);
}
HttpReply *DeviceClassesResource::getStateTypes()
@ -206,7 +206,7 @@ HttpReply *DeviceClassesResource::getStateType(const StateTypeId &stateTypeId)
return reply;
}
}
return createErrorReply(HttpReply::NotFound);
return createDeviceErrorReply(HttpReply::NotFound, DeviceManager::DeviceErrorStateTypeNotFound);
}
HttpReply *DeviceClassesResource::getEventTypes()
@ -230,7 +230,7 @@ HttpReply *DeviceClassesResource::getEventType(const EventTypeId &eventTypeId)
return reply;
}
}
return createErrorReply(HttpReply::NotFound);
return createDeviceErrorReply(HttpReply::NotFound, DeviceManager::DeviceErrorEventTypeNotFound);
}
HttpReply *DeviceClassesResource::getDiscoverdDevices(const ParamList &discoveryParams)
@ -247,7 +247,7 @@ HttpReply *DeviceClassesResource::getDiscoverdDevices(const ParamList &discovery
}
if (status != DeviceManager::DeviceErrorNoError)
return createErrorReply(HttpReply::InternalServerError);
return createDeviceErrorReply(HttpReply::InternalServerError, status);
return createSuccessReply();
}

View File

@ -51,12 +51,12 @@ HttpReply *DevicesResource::proccessRequest(const HttpRequest &request, const QS
DeviceId deviceId = DeviceId(urlTokens.at(3));
if (deviceId.isNull()) {
qCWarning(dcRest) << "Could not parse DeviceId:" << urlTokens.at(3);
return createErrorReply(HttpReply::BadRequest);
return createDeviceErrorReply(HttpReply::BadRequest, DeviceManager::DeviceErrorDeviceNotFound);
}
m_device = GuhCore::instance()->findConfiguredDevice(deviceId);
if (!m_device) {
qCWarning(dcRest) << "Could find any device with DeviceId:" << urlTokens.at(3);
return createErrorReply(HttpReply::NotFound);
return createDeviceErrorReply(HttpReply::NotFound, DeviceManager::DeviceErrorDeviceNotFound);
}
}
@ -106,12 +106,12 @@ HttpReply *DevicesResource::proccessGetRequest(const HttpRequest &request, const
StateTypeId stateTypeId = StateTypeId(urlTokens.at(5));
if (stateTypeId.isNull()) {
qCWarning(dcRest) << "Could not parse StateTypeId:" << urlTokens.at(5);
return createErrorReply(HttpReply::BadRequest);
return createDeviceErrorReply(HttpReply::BadRequest, DeviceManager::DeviceErrorStateTypeNotFound);
}
if (!m_device->hasState(stateTypeId)){
qCWarning(dcRest) << "This device has no StateTypeId:" << urlTokens.at(5);
return createErrorReply(HttpReply::NotFound);
return createDeviceErrorReply(HttpReply::NotFound, DeviceManager::DeviceErrorStateTypeNotFound);
}
return getDeviceStateValue(m_device, stateTypeId);
}
@ -172,7 +172,7 @@ HttpReply *DevicesResource::proccessPostRequest(const HttpRequest &request, cons
ActionTypeId actionTypeId = ActionTypeId(urlTokens.at(5));
if (actionTypeId.isNull()) {
qCWarning(dcRest) << "Could not parse ActionTypeId:" << urlTokens.at(5);
return createErrorReply(HttpReply::BadRequest);
return createDeviceErrorReply(HttpReply::BadRequest, DeviceManager::DeviceErrorActionTypeNotFound);
}
bool found = false;
DeviceClass deviceClass = GuhCore::instance()->findDeviceClass(m_device->deviceClassId());
@ -184,7 +184,7 @@ HttpReply *DevicesResource::proccessPostRequest(const HttpRequest &request, cons
}
if (!found) {
qCWarning(dcRest) << "Could not find ActionTypeId:" << actionTypeId.toString();
return createErrorReply(HttpReply::NotFound);
return createDeviceErrorReply(HttpReply::NotFound, DeviceManager::DeviceErrorActionTypeNotFound);
}
return executeAction(m_device, actionTypeId, request.payload());
@ -263,10 +263,10 @@ HttpReply *DevicesResource::removeDevice(Device *device) const
// TODO: /api/v1/devices/{deviceId}?ruleId={ruleId}&removePolicy={RemovePolicy}
if (result == DeviceManager::DeviceErrorNoError) {
HttpReply *reply = createSuccessReply();
HttpReply *reply = createDeviceErrorReply(HttpReply::Ok, result);
return reply;
}
return createErrorReply(HttpReply::Forbidden);
return createDeviceErrorReply(HttpReply::BadRequest, result);
}
HttpReply *DevicesResource::executeAction(Device *device, const ActionTypeId &actionTypeId, const QByteArray &payload) const
@ -295,9 +295,9 @@ HttpReply *DevicesResource::executeAction(Device *device, const ActionTypeId &ac
}
if (status != DeviceManager::DeviceErrorNoError)
return createErrorReply(HttpReply::InternalServerError);
return createDeviceErrorReply(HttpReply::InternalServerError, status);
return createSuccessReply();
return createDeviceErrorReply(HttpReply::Ok, status);
}
HttpReply *DevicesResource::addConfiguredDevice(const QByteArray &payload) const
@ -310,7 +310,7 @@ HttpReply *DevicesResource::addConfiguredDevice(const QByteArray &payload) const
DeviceClassId deviceClassId(params.value("deviceClassId").toString());
if (deviceClassId.isNull())
return createErrorReply(HttpReply::BadRequest);
return createDeviceErrorReply(HttpReply::BadRequest, DeviceManager::DeviceErrorDeviceClassNotFound);
DeviceId newDeviceId = DeviceId::createDeviceId();
ParamList deviceParams = JsonTypes::unpackParams(params.value("deviceParams").toList());
@ -332,7 +332,7 @@ HttpReply *DevicesResource::addConfiguredDevice(const QByteArray &payload) const
}
if (status != DeviceManager::DeviceErrorNoError)
return createErrorReply(HttpReply::InternalServerError);
return createDeviceErrorReply(HttpReply::InternalServerError, status);
QVariant result = JsonTypes::packDevice(GuhCore::instance()->findConfiguredDevice(newDeviceId));
HttpReply *reply = createSuccessReply();
@ -354,7 +354,7 @@ HttpReply *DevicesResource::pairDevice(const QByteArray &payload) const
if (deviceClassId.isNull()) {
qCWarning(dcRest) << "Could not find deviceClassId" << params.value("deviceClassId").toString();
return createErrorReply(HttpReply::BadRequest);
return createDeviceErrorReply(HttpReply::BadRequest, DeviceManager::DeviceErrorDeviceClassNotFound);
}
qCDebug(dcRest) << "Pair device with deviceClassId" << deviceClassId.toString();
@ -370,7 +370,7 @@ HttpReply *DevicesResource::pairDevice(const QByteArray &payload) const
}
if (status != DeviceManager::DeviceErrorNoError)
return createErrorReply(HttpReply::BadRequest);
return createDeviceErrorReply(HttpReply::BadRequest, status);
QVariantMap returns;
returns.insert("displayMessage", deviceClass.pairingInfo());
@ -402,9 +402,9 @@ HttpReply *DevicesResource::confirmPairDevice(const QByteArray &payload) const
}
if (status != DeviceManager::DeviceErrorNoError)
return createErrorReply(HttpReply::InternalServerError);
return createDeviceErrorReply(HttpReply::InternalServerError, status);
return createSuccessReply();
return createDeviceErrorReply(HttpReply::Ok, DeviceManager::DeviceErrorNoError);
}
HttpReply *DevicesResource::editDevice(Device *device, const QByteArray &payload) const
@ -435,9 +435,9 @@ HttpReply *DevicesResource::editDevice(Device *device, const QByteArray &payload
}
if (status != DeviceManager::DeviceErrorNoError)
return createErrorReply(HttpReply::InternalServerError);
return createDeviceErrorReply(HttpReply::InternalServerError, status);
return createSuccessReply();
return createDeviceErrorReply(HttpReply::Ok, DeviceManager::DeviceErrorNoError);
}
void DevicesResource::actionExecuted(const ActionId &actionId, DeviceManager::DeviceError status)
@ -445,13 +445,21 @@ void DevicesResource::actionExecuted(const ActionId &actionId, DeviceManager::De
if (!m_asyncActionExecutions.contains(actionId))
return; // Not the action we are waiting for.
QVariantMap response;
response.insert("error", JsonTypes::deviceErrorToString(status));
HttpReply *reply = m_asyncActionExecutions.take(actionId);
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
if (status == DeviceManager::DeviceErrorNoError) {
qCDebug(dcRest) << "Action execution finished successfully";
reply->setHttpStatusCode(HttpReply::Ok);
reply->setPayload(QJsonDocument::fromVariant(response).toJson());
} else {
qCDebug(dcRest) << "Action execution finished with error" << status;
QVariantMap response;
response.insert("error", JsonTypes::deviceErrorToString(status));
reply->setHttpStatusCode(HttpReply::InternalServerError);
reply->setPayload(QJsonDocument::fromVariant(response).toJson());
}
reply->finished();
@ -462,13 +470,19 @@ void DevicesResource::deviceSetupFinished(Device *device, DeviceManager::DeviceE
if (!m_asyncDeviceAdditions.contains(device->id()))
return; // Not the device we are waiting for.
QVariantMap response;
response.insert("error", JsonTypes::deviceErrorToString(status));
HttpReply *reply = m_asyncDeviceAdditions.take(device->id());
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
if (status == DeviceManager::DeviceErrorNoError) {
qCDebug(dcRest) << "Device setup finished successfully";
reply->setHttpStatusCode(HttpReply::Ok);
reply->setPayload(QJsonDocument::fromVariant(response).toJson());
} else {
qCDebug(dcRest) << "Device setup finished with error" << status;
reply->setHttpStatusCode(HttpReply::InternalServerError);
reply->setPayload(QJsonDocument::fromVariant(response).toJson());
}
QVariant result = JsonTypes::packDevice(device);
@ -482,13 +496,19 @@ void DevicesResource::deviceEditFinished(Device *device, DeviceManager::DeviceEr
if (!m_asyncEditDevice.contains(device))
return; // Not the device we are waiting for.
QVariantMap response;
response.insert("error", JsonTypes::deviceErrorToString(status));
HttpReply *reply = m_asyncEditDevice.take(device);
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
if (status == DeviceManager::DeviceErrorNoError) {
qCDebug(dcRest) << "Device edit finished successfully";
reply->setHttpStatusCode(HttpReply::Ok);
reply->setPayload(QJsonDocument::fromVariant(response).toJson());
} else {
qCDebug(dcRest) << "Device edit finished with error" << status;
reply->setHttpStatusCode(HttpReply::InternalServerError);
reply->setPayload(QJsonDocument::fromVariant(response).toJson());
}
reply->finished();
@ -499,10 +519,15 @@ void DevicesResource::pairingFinished(const PairingTransactionId &pairingTransac
if (!m_asyncPairingRequests.contains(pairingTransactionId))
return; // Not the device pairing we are waiting for.
QVariantMap response;
response.insert("error", JsonTypes::deviceErrorToString(status));
HttpReply *reply = m_asyncPairingRequests.take(pairingTransactionId);
if (status != DeviceManager::DeviceErrorNoError) {
qCDebug(dcRest) << "Pairing device finished with error.";
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
reply->setHttpStatusCode(HttpReply::InternalServerError);
reply->setPayload(QJsonDocument::fromVariant(response).toJson());
reply->finished();
return;
}

View File

@ -60,6 +60,7 @@
#include "restresource.h"
#include "httprequest.h"
#include "loggingcategories.h"
#include "devicemanager.h"
#include "guhcore.h"
#include <QJsonDocument>
@ -105,6 +106,37 @@ HttpReply *RestResource::createErrorReply(const HttpReply::HttpStatusCode &statu
return reply;
}
/*! Returns the pointer to a new created error \l{HttpReply} initialized with the given \a statusCode, \l{HttpReply::TypeSync} and the \a deviceError. */
HttpReply *RestResource::createDeviceErrorReply(const HttpReply::HttpStatusCode &statusCode, const DeviceManager::DeviceError &deviceError)
{
HttpReply *reply = new HttpReply(statusCode, HttpReply::TypeSync);
QVariantMap response;
response.insert("error", JsonTypes::deviceErrorToString(deviceError));
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
reply->setPayload(QJsonDocument::fromVariant(response).toJson());
return reply;
}
HttpReply *RestResource::createRuleErrorReply(const HttpReply::HttpStatusCode &statusCode, const RuleEngine::RuleError &ruleError)
{
HttpReply *reply = new HttpReply(statusCode, HttpReply::TypeSync);
QVariantMap response;
response.insert("error", JsonTypes::ruleErrorToString(ruleError));
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
reply->setPayload(QJsonDocument::fromVariant(response).toJson());
return reply;
}
HttpReply *RestResource::createLoggingErrorReply(const HttpReply::HttpStatusCode &statusCode, const Logging::LoggingError &loggingError)
{
HttpReply *reply = new HttpReply(statusCode, HttpReply::TypeSync);
QVariantMap response;
response.insert("error", JsonTypes::loggingErrorToString(loggingError));
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
reply->setPayload(QJsonDocument::fromVariant(response).toJson());
return reply;
}
/*! Returns the pointer to a new created \l{HttpReply} initialized with \l{HttpReply::Ok} and \l{HttpReply::TypeAsync}. */
HttpReply *RestResource::createAsyncReply()
{

View File

@ -26,6 +26,7 @@
#include "httpreply.h"
#include "httprequest.h"
#include "jsontypes.h"
class QVariant;
@ -45,6 +46,9 @@ public:
static HttpReply *createSuccessReply();
static HttpReply *createCorsSuccessReply();
static HttpReply *createErrorReply(const HttpReply::HttpStatusCode &statusCode);
static HttpReply *createDeviceErrorReply(const HttpReply::HttpStatusCode &statusCode, const DeviceManager::DeviceError &deviceError);
static HttpReply *createRuleErrorReply(const HttpReply::HttpStatusCode &statusCode, const RuleEngine::RuleError &ruleError);
static HttpReply *createLoggingErrorReply(const HttpReply::HttpStatusCode &statusCode, const Logging::LoggingError &loggingError);
static HttpReply *createAsyncReply();
static QPair<bool, QVariant> verifyPayload(const QByteArray &payload);

View File

@ -566,6 +566,7 @@
"DeviceError": [
"DeviceErrorNoError",
"DeviceErrorPluginNotFound",
"DeviceErrorVendorNotFound",
"DeviceErrorDeviceNotFound",
"DeviceErrorDeviceClassNotFound",
"DeviceErrorActionTypeNotFound",