From 61879c47784570d8053d9ea56109f86ea46ca414 Mon Sep 17 00:00:00 2001
From: Juan Ignacio Ubeira <juan.iu@hotmail.com>
Date: Wed, 22 Feb 2017 10:15:23 -0300
Subject: [PATCH] NativeNodeMain upgraded to upstream error codes to the
 application.

---
 .../java/org/ros/node/NativeNodeMain.java     | 60 +++++++++++++------
 1 file changed, 42 insertions(+), 18 deletions(-)

diff --git a/rosjava/src/main/java/org/ros/node/NativeNodeMain.java b/rosjava/src/main/java/org/ros/node/NativeNodeMain.java
index c7d2ff4d..3ed164e2 100644
--- a/rosjava/src/main/java/org/ros/node/NativeNodeMain.java
+++ b/rosjava/src/main/java/org/ros/node/NativeNodeMain.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2017 Ekumen, Inc.
+ *
+ * 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.
+ */
+
 package org.ros.node;
 
 import org.apache.commons.logging.Log;
@@ -7,11 +23,13 @@ import org.apache.commons.logging.LogFactory;
  * A java wrapper to load and run a native-code ROS node.
  * 
  * Note: there are no actual native methods declared in this class. We only define an interface. The native methods should be declared in the child class.
- * 
+ * Native methods' return codes can be handled by the application using {@link #onError(Node, Throwable)}.
+ *
  * @author ecorbellini@creativa77.com.ar (Ernesto Corbellini)
  */
 public abstract class NativeNodeMain extends AbstractNodeMain {
-  
+
+  public static final int SUCCESS = 0;
   private Log log = LogFactory.getLog(NativeNodeMain.class);
   private String libName;
   private String masterUri = null;
@@ -19,7 +37,9 @@ public abstract class NativeNodeMain extends AbstractNodeMain {
   private String nodeName = null;
   private String[] remappingArguments;
   private boolean shuttingDown = false;
-  
+  protected int executeReturnCode = SUCCESS;
+  protected int shutdownReturnCode = SUCCESS;
+
   /**
    *  @param libName
    *    The name of the library to load.
@@ -36,20 +56,16 @@ public abstract class NativeNodeMain extends AbstractNodeMain {
     }
     
     log.info("Trying to load native library '" + libName + "'...");
-    try
-    {
+    try {
       System.loadLibrary(libName);
     }
-    catch (SecurityException e)
-    {
+    catch (SecurityException e) {
       log.info("Error loading library! SecurityException");
     }
-    catch (UnsatisfiedLinkError e)
-    {
+    catch (UnsatisfiedLinkError e) {
       log.info("Error loading library! UnsatisfiedLinkError");
     }
-    catch (NullPointerException e)
-    {
+    catch (NullPointerException e) {
       log.info("Error loading library! NullPointerException");
     }
   }
@@ -62,10 +78,10 @@ public abstract class NativeNodeMain extends AbstractNodeMain {
     this(libName, null);
   }
 
-  // These methods define the execution model interface for this node. Return values are error codes (not used by default).
+  // These methods define the execution model interface for this node.
   protected abstract int execute(String rosMasterUri, String rosHostName, String rosNodeName, String[] remappingArguments);
   protected abstract int shutdown();
-  
+
   @Override
   public void onStart(final ConnectedNode connectedNode) {
     // retain important ROS info
@@ -77,19 +93,27 @@ public abstract class NativeNodeMain extends AbstractNodeMain {
     new Thread() {
       @Override
       public void run() {
-        execute(masterUri, hostName, nodeName, remappingArguments);
-        
+        executeReturnCode = execute(masterUri, hostName, nodeName, remappingArguments);
+
+        if (executeReturnCode != SUCCESS) {
+          onError(connectedNode, new Throwable(nodeName + " execution error code " + executeReturnCode));
+        }
+
         // node execution has finished so we propagate the shutdown sequence only if we aren't already shutting down for other reasons
-        if(!shuttingDown) {
+        if (!shuttingDown) {
           connectedNode.shutdown();
         }
       }
     }.start();
   }
-  
+
   @Override
   public void onShutdown(Node node) {
     shuttingDown = true;
-    shutdown();
+    shutdownReturnCode = shutdown();
+
+    if (shutdownReturnCode != SUCCESS) {
+      onError(node, new Throwable(nodeName + " shutdown error code " + shutdownReturnCode));
+    }
   }
 }
-- 
GitLab