Skip to content

Commit 9c2ed43

Browse files
committed
catflow: catch errors at setting parameters of JsonObject at restore()
backend: track if model is valid
1 parent 1b9ac30 commit 9c2ed43

File tree

15 files changed

+112
-71
lines changed

15 files changed

+112
-71
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ To see api documentation look at: [catflow/README.md](catflow/README.md)
88
## Install
99
Download [install-packages](https://gitlab.com/PancakeSoftware/openHabAI/-/jobs/artifacts/master/download?job=install-packages) from artifacts. Extract it and install the .deb package.
1010
```bash
11+
cd build/pack
1112
dpkg --install OpenHabAI-0.0.0-Linux.deb
1213
# resolve deps
1314
apt-get install -f
@@ -39,5 +40,7 @@ The compiled trainSever executable can be found in build/bin. <br>
3940
To run frontend: ```make frontendRun``` or see in [README of frontend](frontend-angular/README.md)
4041

4142

42-
#### Protocol
43-
See backend-frontend [protocol definition](./doc/README.md).
43+
#### Development
44+
To use the Websocket Api see backend-frontend [protocol definition](./doc/README.md).
45+
##### Report Bugs and Improvements
46+
If you found a bug or have a good idea for new a feature just [open a new issue at gitlab](https://gitlab.com/PancakeSoftware/openHabAI/issues/new).

catflow/cpp/include/ApiJsonObject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class ApiJsonObject : protected virtual Log, public virtual ApiSubscribable, pub
4040
* @see JsonObject::params()
4141
* @return vector of changed param names
4242
*/
43-
vector<string> fromJson(Json params) override;
43+
vector<string> fromJson(Json params, bool catchParameterErrors = false) override;
4444

4545
/**
4646
* set configured class attributes to values in params

catflow/cpp/include/JsonList.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ class JsonList : public ApiJsonObject, public __JsonList
110110
function<T *(Json params)> createItemFunc = [](Json params) -> T *
111111
{
112112
auto *t = new T();
113-
t->fromJson(params);
114113
return t;
115114
};
116115

catflow/cpp/include/JsonObject.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,17 @@ namespace internal
8383
class JsonParamReadOnly: public AJsonParam{
8484
public:
8585
T* valuePtr;
86+
string key;
8687
JsonParamReadOnly(T &value, string key)
87-
{this->valuePtr = &value;}
88+
{this->valuePtr = &value; this->key = key;}
8889

8990
Json toJson() const override {
9091
return Json(*valuePtr);
9192
}
9293

93-
void fromJson(Json j) override
94-
{}
94+
void fromJson(Json j) override {
95+
throw JsonObjectException("can't set '"+key+"' because it is readonly");
96+
}
9597

9698
bool isPrimitive() override;
9799
};
@@ -163,7 +165,7 @@ class JsonObject
163165
* @see JsonObject::params()
164166
* @return vector of changed param names
165167
*/
166-
virtual vector<string> fromJson(Json params) {
168+
virtual vector<string> fromJson(Json params, bool catchParameterErrors = false) {
167169
/* refresh param pointers
168170
* this is very inefficient but necessary (rebuild whole param list):
169171
* when the object is copied all param pointers have to be redefined (change pointer address) */
@@ -202,9 +204,13 @@ class JsonObject
202204
}
203205
catch (Json::type_error &e) {
204206
l.err("can't set jsonObject key '" + key +"' : " + e.what());
205-
throw JsonObjectException("can't set jsonObject key '" + key +"' because of wrong type : " + e.what());
207+
if (!catchParameterErrors)
208+
throw JsonObjectException("can't set jsonObject key '" + key +"' because of wrong type : " + e.what());
206209
} catch (JsonObjectException &e) {
207-
throw JsonObjectException("can't set jsonObject key '" + key +"' because of JsonObjectException : " + e.what());
210+
if (!catchParameterErrors)
211+
throw JsonObjectException("can't set jsonObject key '" + key +"' because of JsonObjectException : " + e.what());
212+
else
213+
l.err("can't set jsonObject key '" + key +"' because of JsonObjectException : " + e.what());
208214
}
209215
}
210216

catflow/cpp/source/ApiJsonObject.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ ApiJsonObject::ApiJsonObject(Json params)
2525
fromJson(params);
2626
}
2727

28-
vector<string> ApiJsonObject::fromJson(Json params)
28+
vector<string> ApiJsonObject::fromJson(Json params, bool catchParameterErrors)
2929
{
30-
vector<string> changedParams = JsonObject::fromJson(params);
30+
vector<string> changedParams = JsonObject::fromJson(params, catchParameterErrors);
3131

3232
// save all
3333
storeMe();
@@ -102,7 +102,7 @@ bool ApiJsonObject::load(string path, string fileName)
102102
return false;
103103
}
104104

105-
fromJson(params);
105+
fromJson(params, true /*catch param assignment errors*/);
106106
ok("load from " + full);
107107
return true;
108108
}

catflow/cpp/source/JsonList.tpp

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ ApiRespond* JsonList<T>::processApi(ApiRequest request)
106106
T* n = createItemFunc(j);
107107
if (n != nullptr)
108108
{
109+
n->fromJson(j, true /*catch param assignment errors*/);
109110
items.insert({idAutoIncrement, n});
110111
if (route.is_initialized() && is_base_of<ApiJsonObject, T>::value)
111112
{
@@ -268,50 +269,60 @@ void JsonList<T>::restore()
268269
/*
269270
* get id by directory name */
270271
string id = directory_iterator->path().filename().string();
271-
int idNum;
272272
try
273273
{
274-
idNum = stoi(id);
275-
} catch (invalid_argument& e)
276-
{
277-
err("entity's id (in directoryName '" + directory_iterator->path().string() + "') is not a number", e.what());
278-
continue;
279-
}
280-
//info("... restore: " + storePath.get() + "/" + id);
281274

282-
/*
283-
* read item.json */
284-
Json params;
285-
try
286-
{
287-
ifstream item{this->route.get().toStringStorePath() + id + "/item.json"};
288-
stringstream sItem;
289-
sItem << item.rdbuf();
290-
params = Json::parse(sItem.str());
275+
int idNum;
276+
try
277+
{
278+
idNum = stoi(id);
279+
} catch (invalid_argument &e)
280+
{
281+
err("entity's id (in directoryName '" + directory_iterator->path().string() + "') is not a number", e.what());
282+
continue;
283+
}
284+
//info("... restore: " + storePath.get() + "/" + id);
285+
286+
/*
287+
* read item.json */
288+
Json params;
289+
try
290+
{
291+
ifstream item{this->route.get().toStringStorePath() + id + "/item.json"};
292+
stringstream sItem;
293+
sItem << item.rdbuf();
294+
params = Json::parse(sItem.str());
295+
}
296+
catch (exception &e)
297+
{
298+
err("read item '" + this->route.get().toStringStorePath() + id + "/item.json" + "' : " + string(e.what()));
299+
directory_iterator++;
300+
continue;
301+
}
302+
303+
/*
304+
* add item */
305+
T *n = createItemFunc(params);
306+
ApiMessageRoute nRoute = route.get();
307+
nRoute.push(id); // set entity id
308+
n->setRoute(nRoute);
309+
items.insert({idNum, n});
310+
n->restore();
311+
312+
// next
313+
if (idNum >= idAutoIncrement)
314+
idAutoIncrement = idNum + 1;
315+
directory_iterator++;
291316
}
292-
catch (exception& e) {
293-
err("read item '"+ this->route.get().toStringStorePath() + id + "/item.json" +"' : " + string(e.what()));
317+
catch (exception &e)
318+
{
319+
err("restore (" + this->route.get().toStringStorePath() + " id(" + id + ")): " + string(e.what()));
294320
directory_iterator++;
295-
continue;
296321
}
297-
298-
/*
299-
* add item */
300-
T *n = createItemFunc(params);
301-
ApiMessageRoute nRoute = route.get();
302-
nRoute.push(id); // set entity id
303-
n->setRoute(nRoute);
304-
items.insert({idNum, n});
305-
n->restore();
306-
307-
// next
308-
if (idNum >= idAutoIncrement)
309-
idAutoIncrement = idNum + 1;
310-
directory_iterator++;
311322
}
312323
}
313324
catch (exception &e){
314-
err("restore ("+this->route.get().toStringStorePath()+"): " + string(e.what()));
325+
err("restore ("+this->route.get().toStringStorePath()+" all list items): " + string(e.what()));
315326
}
316327
}
317328

catflow/cpp/test/ApiTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class RootRoute : public ApiRoute
7777
TEST(ApiRouteTest, progressListAddGetRemove)
7878
{
7979
RootRoute root;
80-
root.setStorePath("../test/apiTest/");
80+
root.setStorePath("./test/apiTest/");
8181

8282
/*
8383
* Add tow courses: SystemParallelProgramming, and Math1
@@ -121,7 +121,7 @@ TEST(ApiRouteTest, progressListAddGetRemove)
121121
*/
122122
root.store();
123123
RootRoute rootRestored;
124-
rootRestored.setStorePath("../test/apiTest/");
124+
rootRestored.setStorePath("./test/apiTest/");
125125
rootRestored.restore();
126126
EXPECT_EQ(2, rootRestored.courses.length());
127127
EXPECT_EQ(3, rootRestored.courses.get(0).students.length());

catflow/cpp/test/JsonObjectTest.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,14 @@ TEST(JsonObjectTest, saveLoad)
7373

7474
MyObject myObject;
7575
myObject.fromJson(val);
76-
myObject.save("../test/", "testJsonObject.json");
76+
myObject.save("./test/", "testJsonObject.json");
7777
cout << "save finish" << endl;
7878

7979

8080
MyObject myObjectNew;
8181

8282
cout << "now load" << endl;
83-
myObjectNew.load("../test/", "testJsonObject.json");
83+
myObjectNew.load("./test/", "testJsonObject.json");
8484

8585

8686
EXPECT_EQ(20, myObjectNew.i);
@@ -221,7 +221,7 @@ TEST(JsonObjectTest, notifyParamsChanged)
221221
EXPECT_EQ(0, Catflow::requestsToSend.size());
222222

223223
MyObject obj;
224-
obj.setStorePath("../test/jsonObjectTest");
224+
obj.setStorePath("./test/jsonObjectTest");
225225
ApiRequest sub("", "subscribe");
226226
sub.client = new VoidClient();
227227
obj.processApi(sub);

frontend-angular/src/app/project/model-edit/model-editor/model-editor.component.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ <h5>Add Layer</h5>
1818
<div style="margin-top: 40px">
1919
<div class="btn waves-effect green" (click)="saveModel()">Save Model <i class="material-icons right">save</i></div>
2020
</div>
21+
22+
<a style="margin-top: 10px;" [ngClass]="modelValid ? 'green-text' : 'red-text'" class="btn white btn-flat no-select">{{modelValid ? 'Model is valid' : 'Model is invalid'}}
23+
<i [ngClass]="modelValid ? 'green-text' : 'red-text'" class="material-icons red-text right">{{modelValid ? 'done' : 'warning'}}</i></a>
24+
2125
<pre>{{modelJson | json}}</pre>
2226
</div>
2327

frontend-angular/src/app/project/model-edit/model-editor/model-editor.component.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export class ModelEditorComponent implements OnInit, AfterViewInit, OnDestroy {
3232
nodes: ModelEditorNodeComponent[] = [];
3333
connections: ModelEditorConnectionComponent[] = [];
3434
modelJson: any[] = [];
35+
modelValid: boolean = false;
3536

3637
constructor(
3738
private el: ElementRef,
@@ -162,11 +163,16 @@ export class ModelEditorComponent implements OnInit, AfterViewInit, OnDestroy {
162163
this.networkObj = obj;
163164

164165
// load graph
165-
this.networkObj.object().takeUntil(componentDestroyed(this)).takeUntil(this.onRefresh).subscribe((obj) => {
166-
if (obj == null)
166+
this.networkObj.objectChanged().takeUntil(componentDestroyed(this)).takeUntil(this.onRefresh).subscribe((changed) => {
167+
if (changed == null)
167168
return;
168-
this.modelJson = obj.modelDefinition;
169-
this.modelFromJson(this.modelJson);
169+
if (changed.changedKeys.includes('modelDefinition')) {
170+
this.modelJson = changed.object.modelDefinition;
171+
this.modelFromJson(this.modelJson);
172+
}
173+
if (changed.changedKeys.includes('modelValid')) {
174+
this.modelValid = changed.object.modelValid;
175+
}
170176
});
171177
this.networkObj.subscribe();
172178
}

0 commit comments

Comments
 (0)