OpenSILEX / opensilexClientToolsPython

1 stars 0 forks source link

Error-handling for DevicesAPI fails #1

Open Dryocopus opened 3 years ago

Dryocopus commented 3 years ago

When calling DevicesAPI.create_device() with the following body: {

"uri": "",
"rdf_type": "vocabulary:Actuator",
"name": "Conveyor_NPECGreenhouse_compartment_1",
"brand": "SMO",
"constructor_model": "",
"serial_number": "",
"person_in_charge": "os-usr:rick.van-de-zedde", 
"start_up": "2021-05-01",
"removal": "",
"relations": [
    {
    "property": "",
    "value": ""
  }
],
"description": "Conveyor in NPEC Greenhouse, compartment 1",
"metadata": {}

}, An error occurs like this:

"result" : { "title" : "Unexpected internal error - java.lang.NullPointerException", "message" : null, "stack" : [ "org.opensilex.core.device.api.DeviceAPI.check(DeviceAPI.java:353)", "org.opensilex.core.device.api.DeviceAPI.createDevice(DeviceAPI.java:154)" ], "fullstack" : [ "org.opensilex.core.device.api.DeviceAPI.check(DeviceAPI.java:353)", "org.opensilex.core.device.api.DeviceAPI.createDevice(DeviceAPI.java:154)", "java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)", "java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)", "java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)", "java.base/java.lang.reflect.Method.invoke(Method.java:566)", "org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)", "org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)", "org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)", "org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176)", "org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)", "org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:469)", "org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:391)", "org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:80)", "org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255)", "org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)", "org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)", "org.glassfish.jersey.internal.Errors.process(Errors.java:292)", "org.glassfish.jersey.internal.Errors.process(Errors.java:274)", "org.glassfish.jersey.internal.Errors.process(Errors.java:244)", "org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)", "org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234)", "org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:680)", "org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394)", "org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)", "org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:366)", "org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:319)", "org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)", "org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)", "org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)", "org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)", "org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)", "org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)", "org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)", "org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)", "org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)", "org.apache.catalina.valves.StuckThreadDetectionValve.invoke(StuckThreadDetectionValve.java:206)", "org.apache.catalina.valves.rewrite.RewriteValve.invoke(RewriteValve.java:295)", "org.apapache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)", "org.apache.catalina.valves.rewrite.RewriteValve.invoke(RewriteValve.java:552)", "org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)", "org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)", "org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)", "org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)", "org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)", "org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)", "org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)", "org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)", "org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)", "java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)", "java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)", "org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)", "java.base/java.lang.Thread.run(Thread.java:829)" ] } }

Cause is the empty entry in the relations, so user-input error, but the error-handling could be enhanced.

niio972 commented 3 years ago

Hi @Dryocopus, thank you for your feedback. Have you try to send a DeviceCreationDTO python object or only a dictionary structure though the function parameters ?

In fact you're right a better error-handling could be done. We will take it into account.

Dryocopus commented 3 years ago

Hi, It is in a DeviceCreationDTO. I've stored these things as JSON, but send them as objects. And if I just remove the empty relation it works, so most like that's the cause. Unless something goes wrong at my side in the conversion of the deeper levels of the JSON to objects. But I just use a standard call for that like this:
device_creation_dto = opensilexClientToolsPython.DeviceCreationDTO(**device_creation_dto_as_dict) If that step goes wrong with nested objects anyway it would also fail if there is a valid relations entry. I haven't yet tried that, I'm still struggling with a lot of things in the API-calls. But I'll try that option later.

Peter Roos, NPEC

Dryocopus commented 3 years ago

It looks like the concept works if the relations-list just contains correct properties. So far, I couldn’t find a meaningful property that was accepted by the system (most properties are rejected with messages like ‘Invalid relation value for vocabulary:hasPart => os:set/devices/spectrometer-xyz’), but the following JSON is apparently technically allowed, and is loaded correctly into the system including the relation to the variable.

 {
    "uri": "",
    "rdf_type": "vocabulary:SensingDevice",
    "name": "Conveyor_NPECGreenhouse_compartment_14",
    "brand": "SMO",
    "constructor_model": "",
    "serial_number": "",
    "person_in_charge": "os-usr:rick.van-de-zedde", 
    "start_up": "2021-05-01",
    "removal": "",
    "relations": [
          {
        "property": "vocabulary:measures",
        "value": "http://www.opensilex.org/set/variables#variable.plant_height_looking_very_good_km"
      }
    ],
    "description": "Conveyor in NPEC Greenhouse, compartment 1",
    "metadata": {}
  },

So on the PHIS side it’s indeed just a matter of enhancing the error handling, and on my side making sure that no empty relations are added. And I have to find out which properties are semantically allowed, but that’s a different story.