You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by np...@apache.org on 2018/05/14 07:29:13 UTC

[sling-org-apache-sling-pipes] branch master updated: SLING-7638 make script exception fail the pipe

This is an automated email from the ASF dual-hosted git repository.

npeltier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-pipes.git


The following commit(s) were added to refs/heads/master by this push:
     new f78914e  SLING-7638 make script exception fail the pipe
f78914e is described below

commit f78914efd0aadc5a8a8f5e926828ee48bb9be97c
Author: Nicolas Peltier <pe...@gmail.com>
AuthorDate: Sun May 6 01:01:45 2018 +0200

    SLING-7638 make script exception fail the pipe
    
    - split base pipe's getOutput by using protected computeOutput that spits exception,
    - delegate error handling to base pipe in most cases,
    - remote useless custom output writer, and treat error handling of script exception by writing empty string for csv or json"
---
 pom.xml                                            | 13 ++--
 .../sling/pipes/AbstractInputStreamPipe.java       | 11 ++--
 src/main/java/org/apache/sling/pipes/BasePipe.java | 45 +++++++++----
 .../org/apache/sling/pipes/CustomOutputWriter.java | 39 -----------
 .../java/org/apache/sling/pipes/OutputWriter.java  |  2 +-
 src/main/java/org/apache/sling/pipes/Pipe.java     |  5 +-
 .../java/org/apache/sling/pipes/PipeBindings.java  | 40 +++++-------
 .../java/org/apache/sling/pipes/ReferencePipe.java |  2 +-
 .../sling/pipes/internal/AuthorizablePipe.java     | 31 ++++-----
 .../org/apache/sling/pipes/internal/CsvWriter.java | 25 +++++--
 .../apache/sling/pipes/internal/FilterPipe.java    | 51 +++++++--------
 .../apache/sling/pipes/internal/JsonWriter.java    | 30 +++++----
 .../org/apache/sling/pipes/internal/MovePipe.java  |  2 +-
 .../sling/pipes/internal/MultiPropertyPipe.java    |  3 +-
 .../org/apache/sling/pipes/internal/NotPipe.java   |  2 +-
 .../apache/sling/pipes/internal/PackagePipe.java   | 23 +++----
 .../org/apache/sling/pipes/internal/PathPipe.java  |  3 +-
 .../sling/pipes/internal/PipeBuilderImpl.java      |  4 +-
 .../apache/sling/pipes/internal/RemovePipe.java    | 22 +++----
 .../apache/sling/pipes/internal/TraversePipe.java  |  2 +-
 .../org/apache/sling/pipes/internal/WritePipe.java | 15 ++---
 .../org/apache/sling/pipes/internal/XPathPipe.java |  3 +-
 .../sling/pipes/internal/inputstream/CsvPipe.java  | 65 +++++++++---------
 .../sling/pipes/internal/inputstream/JsonPipe.java | 76 ++++++++++------------
 .../pipes/internal/inputstream/RegexpPipe.java     |  6 +-
 .../AbstractExpressionSlingQueryPipe.java          | 13 +++-
 .../slingquery/AbstractSlingQueryPipe.java         |  4 +-
 .../java/org/apache/sling/pipes/package-info.java  |  2 +-
 .../sling/pipes/internal/PlumberServletTest.java   |  5 +-
 29 files changed, 261 insertions(+), 283 deletions(-)

diff --git a/pom.xml b/pom.xml
index 31d622e..b09f9db 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,7 +29,7 @@
   </parent>
 
   <artifactId>org.apache.sling.pipes</artifactId>
-  <version>2.1.0-SNAPSHOT</version>
+  <version>3.0.0-SNAPSHOT</version>
 
   <name>Apache Sling Pipes</name>
   <description>bulk content changes tool</description>
@@ -218,6 +218,12 @@
       <version>1.3.2</version>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.jackrabbit.vault</groupId>
+      <artifactId>org.apache.jackrabbit.vault</artifactId>
+      <version>3.1.44</version>
+      <scope>provided</scope>
+    </dependency>
     <!-- testing -->
     <dependency>
       <groupId>junit</groupId>
@@ -321,10 +327,5 @@
       <version>2.8.2</version>
       <scope>test</scope>
     </dependency>
-      <dependency>
-          <groupId>org.apache.jackrabbit.vault</groupId>
-          <artifactId>org.apache.jackrabbit.vault</artifactId>
-          <version>3.1.44</version>
-      </dependency>
   </dependencies>
 </project>
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/pipes/AbstractInputStreamPipe.java b/src/main/java/org/apache/sling/pipes/AbstractInputStreamPipe.java
index eb7a37d..a2eff74 100644
--- a/src/main/java/org/apache/sling/pipes/AbstractInputStreamPipe.java
+++ b/src/main/java/org/apache/sling/pipes/AbstractInputStreamPipe.java
@@ -74,7 +74,7 @@ public abstract class AbstractInputStreamPipe extends BasePipe {
         client.getParams().setAuthenticationPreemptive(false);
     }
 
-    InputStream getInputStream() throws IOException {
+    InputStream getInputStream() throws Exception {
         String expr = getExpr();
         if (expr.startsWith(REMOTE_START)) {
             //first look at
@@ -104,21 +104,18 @@ public abstract class AbstractInputStreamPipe extends BasePipe {
         return binding;
     }
 
-    abstract public Iterator<Resource> getOutput(InputStream inputStream);
+    abstract public Iterator<Resource> getOutput(InputStream inputStream) throws Exception;
 
     @Override
-    public Iterator<Resource> getOutput() {
+    public Iterator<Resource> computeOutput() throws Exception {
         try {
             is = getInputStream();
             return getOutput(is);
-        } catch (Exception e){
-            LOGGER.error("unable to fecth input stream", e);
-        } finally {
+        }  finally {
             IOUtils.closeQuietly(is);
             if (method != null){
                 method.releaseConnection();
             }
         }
-        return EMPTY_ITERATOR;
     }
 }
diff --git a/src/main/java/org/apache/sling/pipes/BasePipe.java b/src/main/java/org/apache/sling/pipes/BasePipe.java
index d874655..511a1e1 100644
--- a/src/main/java/org/apache/sling/pipes/BasePipe.java
+++ b/src/main/java/org/apache/sling/pipes/BasePipe.java
@@ -23,6 +23,7 @@ import org.apache.sling.api.resource.ValueMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.script.ScriptException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
@@ -97,14 +98,18 @@ public class BasePipe implements Pipe {
     public boolean isDryRun() {
         if (dryRunObject == null) {
             dryRunObject = false;
-            Object run =  bindings.isBindingDefined(DRYRUN_KEY) ? bindings.instantiateObject(DRYRUN_EXPR) : false;
-            if (run != null) {
-                dryRunObject = true;
-                if (run instanceof Boolean){
-                    dryRunObject = (Boolean)run;
-                } else if (run instanceof String && String.format("%s", Boolean.FALSE).equals(run)){
-                    dryRunObject = false;
+            try {
+                Object run = bindings.isBindingDefined(DRYRUN_KEY) ? bindings.instantiateObject(DRYRUN_EXPR) : false;
+                if (run != null) {
+                    dryRunObject = true;
+                    if (run instanceof Boolean) {
+                        dryRunObject = (Boolean) run;
+                    } else if (run instanceof String && String.format("%s", Boolean.FALSE).equals(run)) {
+                        dryRunObject = false;
+                    }
                 }
+            } catch (ScriptException e){
+                logger.error("error evaluating {}, assuming dry run", DRYRUN_EXPR, e);
             }
         }
         return dryRunObject;
@@ -129,7 +134,7 @@ public class BasePipe implements Pipe {
      * Get pipe's expression, instanciated or not
      * @return configured expression
      */
-    public String getExpr(){
+    public String getExpr() throws ScriptException {
         String rawExpression = properties.get(PN_EXPR, "");
         return bindings.instantiateExpression(rawExpression);
     }
@@ -138,13 +143,13 @@ public class BasePipe implements Pipe {
      * Get pipe's path, instanciated or not
      * @return configured path (can be empty)
      */
-    public String getPath() {
+    public String getPath() throws ScriptException {
         String rawPath = properties.get(PN_PATH, "");
         return bindings.instantiateExpression(rawPath);
     }
 
     @Override
-    public Resource getConfiguredInput() {
+    public Resource getConfiguredInput() throws ScriptException {
         Resource configuredInput = null;
         String path = getPath();
         if (StringUtils.isNotBlank(path)){
@@ -165,7 +170,7 @@ public class BasePipe implements Pipe {
     }
 
     @Override
-    public Resource getInput() {
+    public Resource getInput() throws ScriptException {
         Resource resource = getConfiguredInput();
         if (resource == null && parent != null){
             Pipe previousPipe = getPreviousPipe();
@@ -202,9 +207,23 @@ public class BasePipe implements Pipe {
      * default execution, just returns current resource
      * @return output of this pipe, which is here the input resource
      */
-    public Iterator<Resource> getOutput(){
+    public Iterator<Resource> getOutput() {
+        try {
+            return computeOutput();
+        } catch (Exception e){
+            logger.error("error with pipe execution ", e);
+        }
+        return EMPTY_ITERATOR;
+    }
+
+    /**
+     *
+     * @return
+     * @throws ScriptException
+     */
+    protected Iterator<Resource> computeOutput() throws Exception {
         Resource resource = getInput();
-        if (resource != null){
+        if (resource != null) {
             return Collections.singleton(resource).iterator();
         }
         return EMPTY_ITERATOR;
diff --git a/src/main/java/org/apache/sling/pipes/CustomOutputWriter.java b/src/main/java/org/apache/sling/pipes/CustomOutputWriter.java
deleted file mode 100644
index b618aff..0000000
--- a/src/main/java/org/apache/sling/pipes/CustomOutputWriter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.sling.pipes;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.SlingHttpServletResponse;
-import org.apache.sling.api.resource.Resource;
-
-import java.io.IOException;
-import java.util.HashMap;
-
-public abstract class CustomOutputWriter extends OutputWriter {
-
-    @Override
-    public void init(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
-        super.init(request, response);
-
-    }
-
-    @Override
-    public void setPipe(Pipe pipe) {
-        super.setPipe(pipe);
-
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/pipes/OutputWriter.java b/src/main/java/org/apache/sling/pipes/OutputWriter.java
index a6df8fd..ac32531 100644
--- a/src/main/java/org/apache/sling/pipes/OutputWriter.java
+++ b/src/main/java/org/apache/sling/pipes/OutputWriter.java
@@ -33,7 +33,7 @@ import java.util.Map;
  * defines how pipe's output get written to a servlet response or output stream
  */
 public abstract class OutputWriter {
-    Logger log = LoggerFactory.getLogger(CustomOutputWriter.class);
+    Logger log = LoggerFactory.getLogger(OutputWriter.class);
 
     public static final String KEY_SIZE = "size";
 
diff --git a/src/main/java/org/apache/sling/pipes/Pipe.java b/src/main/java/org/apache/sling/pipes/Pipe.java
index ca76c96..b1f8a74 100644
--- a/src/main/java/org/apache/sling/pipes/Pipe.java
+++ b/src/main/java/org/apache/sling/pipes/Pipe.java
@@ -19,6 +19,7 @@ package org.apache.sling.pipes;
 import org.apache.sling.api.resource.Resource;
 import org.osgi.annotation.versioning.ConsumerType;
 
+import javax.script.ScriptException;
 import java.util.Iterator;
 
 /**
@@ -85,14 +86,14 @@ public interface Pipe {
      * Get the pipe's optional configured resource or null
      * @return input if configured
      */
-    Resource getConfiguredInput();
+    Resource getConfiguredInput() throws ScriptException;
 
     /**
      * Get pipe current's resource *before* next execution, meaning either the
      * configured resource, either previous' pipe output resource
      * @return input, configured or previous pipe
      */
-    Resource getInput();
+    Resource getInput() throws ScriptException;
 
 
     /**
diff --git a/src/main/java/org/apache/sling/pipes/PipeBindings.java b/src/main/java/org/apache/sling/pipes/PipeBindings.java
index d28ffe7..190732d 100644
--- a/src/main/java/org/apache/sling/pipes/PipeBindings.java
+++ b/src/main/java/org/apache/sling/pipes/PipeBindings.java
@@ -267,40 +267,32 @@ public class PipeBindings {
      * we implement here as a String
      * @param expr ecma like expression
      * @return String that is the result of the expression
+     * @throws ScriptException
      */
-    public String instantiateExpression(String expr){
-        try {
-            return (String)evaluate(expr);
-        } catch (ScriptException e) {
-            log.error("Unable to evaluate the script", e);
-        }
-        return expr;
+    public String instantiateExpression(String expr) throws ScriptException {
+        return (String)evaluate(expr);
     }
 
     /**
      * Instantiate object from expression
      * @param expr ecma expression
      * @return instantiated object
+     * @throws ScriptException
      */
-    public Object instantiateObject(String expr){
-        try {
-            Object result = evaluate(expr);
-            if (result != null && ! result.getClass().getName().startsWith("java.lang.")) {
-                //special case of the date in which case jdk.nashorn.api.scripting.ScriptObjectMirror will
-                //be returned
-                JsDate jsDate = ((Invocable) engine).getInterface(result, JsDate.class);
-                if (jsDate != null ) {
-                    Date date = new Date(jsDate.getTime() + jsDate.getTimezoneOffset() * 60 * 1000);
-                    Calendar cal = Calendar.getInstance();
-                    cal.setTime(date);
-                    return cal;
-                }
+    public Object instantiateObject(String expr) throws ScriptException {
+        Object result = evaluate(expr);
+        if (result != null && ! result.getClass().getName().startsWith("java.lang.")) {
+            //special case of the date in which case jdk.nashorn.api.scripting.ScriptObjectMirror will
+            //be returned
+            JsDate jsDate = ((Invocable) engine).getInterface(result, JsDate.class);
+            if (jsDate != null ) {
+                Date date = new Date(jsDate.getTime() + jsDate.getTimezoneOffset() * 60 * 1000);
+                Calendar cal = Calendar.getInstance();
+                cal.setTime(date);
+                return cal;
             }
-            return result;
-        } catch (ScriptException e) {
-            log.error("Unable to evaluate the script for expr {} ", expr, e);
         }
-        return expr;
+        return result;
     }
 
     /**
diff --git a/src/main/java/org/apache/sling/pipes/ReferencePipe.java b/src/main/java/org/apache/sling/pipes/ReferencePipe.java
index 41bcc8c..798e688 100644
--- a/src/main/java/org/apache/sling/pipes/ReferencePipe.java
+++ b/src/main/java/org/apache/sling/pipes/ReferencePipe.java
@@ -63,7 +63,7 @@ public class ReferencePipe extends BasePipe {
     }
 
     @Override
-    public Iterator<Resource> getOutput() {
+    protected Iterator<Resource> computeOutput() throws Exception {
         log.debug("getting {} output", reference);
         return reference.getOutput();
     }
diff --git a/src/main/java/org/apache/sling/pipes/internal/AuthorizablePipe.java b/src/main/java/org/apache/sling/pipes/internal/AuthorizablePipe.java
index 5a89e5a..f7fb73a 100644
--- a/src/main/java/org/apache/sling/pipes/internal/AuthorizablePipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/AuthorizablePipe.java
@@ -86,24 +86,21 @@ public class AuthorizablePipe extends BasePipe {
     }
 
     @Override
-    public Iterator<Resource> getOutput() {
-        try {
-            Authorizable auth = getAuthorizable();
-            if (auth != null) {
-                logger.debug("Retrieved authorizable {}", auth.getID());
-                if (StringUtils.isNotBlank(addToGroup)){
-                    addToGroup(auth);
-                }
-                if (StringUtils.isNotBlank(addMembers)){
-                    addMembers(auth);
-                }
-                if (bindMembers){
-                    bindMembers(auth);
-                }
-                Resource resource = resolver.getResource(auth.getPath());
-                return Collections.singleton(resource).iterator();
+    public Iterator<Resource> computeOutput() throws Exception {
+        Authorizable auth = getAuthorizable();
+        if (auth != null) {
+            logger.debug("Retrieved authorizable {}", auth.getID());
+            if (StringUtils.isNotBlank(addToGroup)){
+                addToGroup(auth);
             }
-        } catch (Exception e){
+            if (StringUtils.isNotBlank(addMembers)){
+                addMembers(auth);
+            }
+            if (bindMembers){
+                bindMembers(auth);
+            }
+            Resource resource = resolver.getResource(auth.getPath());
+            return Collections.singleton(resource).iterator();
         }
         return EMPTY_ITERATOR;
     }
diff --git a/src/main/java/org/apache/sling/pipes/internal/CsvWriter.java b/src/main/java/org/apache/sling/pipes/internal/CsvWriter.java
index 7ca5f38..49a38c5 100644
--- a/src/main/java/org/apache/sling/pipes/internal/CsvWriter.java
+++ b/src/main/java/org/apache/sling/pipes/internal/CsvWriter.java
@@ -16,19 +16,22 @@
  */
 package org.apache.sling.pipes.internal;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.Resource;
-import org.apache.sling.pipes.CustomOutputWriter;
+import org.apache.sling.pipes.OutputWriter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.script.ScriptException;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 
-public class CsvWriter extends CustomOutputWriter {
+public class CsvWriter extends OutputWriter {
     private static final Logger LOG = LoggerFactory.getLogger(CsvWriter.class);
 
     private static final String CSV_EXTENSION = "csv";
@@ -71,10 +74,20 @@ public class CsvWriter extends CustomOutputWriter {
         }
         if (headers != null){
             try {
-                String line = headers.stream().map(key -> key.equals(PATH_KEY) ?
-                        resource.getPath()
-                        : (String)pipe.getBindings().instantiateObject((String)customOutputs.get(key)))
-                        .collect(Collectors.joining(SEPARATOR));
+                List<String> elts = new ArrayList<>();
+                for (String key : headers){
+                    if (key.equals(PATH_KEY)){
+                        elts.add(resource.getPath());
+                    } else {
+                        try {
+                            elts.add(pipe.getBindings().instantiateExpression((String)customOutputs.get(key)));
+                        } catch (ScriptException e){
+                            LOG.error("unable to evalutate {}, will write empty value", customOutputs.get(key), e);
+                            elts.add(StringUtils.EMPTY);
+                        }
+                    }
+                }
+                String line = elts.stream().collect(Collectors.joining(SEPARATOR));
                 writer.write(line + NEW_LINE);
             } catch (IOException e) {
                 LOG.error("unable to write header", e);
diff --git a/src/main/java/org/apache/sling/pipes/internal/FilterPipe.java b/src/main/java/org/apache/sling/pipes/internal/FilterPipe.java
index 35ea6ab..53deda8 100644
--- a/src/main/java/org/apache/sling/pipes/internal/FilterPipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/FilterPipe.java
@@ -25,7 +25,8 @@ import org.slf4j.LoggerFactory;
 
 import javax.jcr.Node;
 import javax.jcr.NodeIterator;
-import java.util.Collections;
+import javax.jcr.RepositoryException;
+import javax.script.ScriptException;
 import java.util.Iterator;
 import java.util.regex.Pattern;
 
@@ -44,7 +45,7 @@ public class FilterPipe extends BasePipe {
         super(plumber, resource);
     }
 
-    boolean propertiesPass(ValueMap current, ValueMap filter){
+    boolean propertiesPass(ValueMap current, ValueMap filter) throws ScriptException {
         if (filter.containsKey(PN_TEST)){
             Object test = bindings.instantiateObject(filter.get(PN_TEST, "${false}"));
             if (! (test instanceof Boolean)){
@@ -64,37 +65,33 @@ public class FilterPipe extends BasePipe {
         return true;
     }
 
-    boolean filterPasses(Resource currentResource, Resource filterResource){
-        try {
-            ValueMap current = currentResource.adaptTo(ValueMap.class);
-            ValueMap filter = filterResource.adaptTo(ValueMap.class);
-            if (propertiesPass(current, filter)) {
-                Node currentNode = currentResource.adaptTo(Node.class);
-                boolean noChildren = (Boolean) bindings.instantiateObject(filter.get(PN_NOCHILDREN, "${false}"));
-                if (noChildren) {
-                    return !currentNode.hasNodes();
-                } else {
-                    Node filterNode = filterResource.adaptTo(Node.class);
-                    boolean returnValue = true;
-                    for (NodeIterator children = filterNode.getNodes(); returnValue && children.hasNext();){
-                        String childName = children.nextNode().getName();
-                        if (!currentNode.hasNode(childName)){
-                            return false;
-                        } else {
-                            returnValue &= filterPasses(currentResource.getChild(childName), filterResource.getChild(childName));
-                        }
+    boolean filterPasses(Resource currentResource, Resource filterResource) throws ScriptException, RepositoryException {
+        ValueMap current = currentResource.adaptTo(ValueMap.class);
+        ValueMap filter = filterResource.adaptTo(ValueMap.class);
+        if (propertiesPass(current, filter)) {
+            Node currentNode = currentResource.adaptTo(Node.class);
+            boolean noChildren = (Boolean) bindings.instantiateObject(filter.get(PN_NOCHILDREN, "${false}"));
+            if (noChildren) {
+                return !currentNode.hasNodes();
+            } else {
+                Node filterNode = filterResource.adaptTo(Node.class);
+                boolean returnValue = true;
+                for (NodeIterator children = filterNode.getNodes(); returnValue && children.hasNext();){
+                    String childName = children.nextNode().getName();
+                    if (!currentNode.hasNode(childName)){
+                        return false;
+                    } else {
+                        returnValue &= filterPasses(currentResource.getChild(childName), filterResource.getChild(childName));
                     }
-                    return returnValue;
                 }
+                return returnValue;
             }
-        } catch (Exception e){
-            logger.error("error when executing filter", e);
         }
         return false;
     }
 
     @Override
-    public Iterator<Resource> getOutput() {
+    protected Iterator<Resource> computeOutput() throws Exception {
         Resource resource = getInput();
         if (resource != null){
             boolean not = properties.get(PN_NOT, false);
@@ -104,11 +101,11 @@ public class FilterPipe extends BasePipe {
             // - all the other combinations should pass
             if (filterPasses(resource, getConfiguration()) ^ not){
                 logger.debug("filter passes for {}", resource.getPath());
-                return super.getOutput();
+                return super.computeOutput();
             } else {
                 logger.debug("{} got filtered out", resource.getPath());
             }
         }
-        return Collections.emptyIterator();
+        return EMPTY_ITERATOR;
     }
 }
diff --git a/src/main/java/org/apache/sling/pipes/internal/JsonWriter.java b/src/main/java/org/apache/sling/pipes/internal/JsonWriter.java
index 762c8a5..81ba1a3 100644
--- a/src/main/java/org/apache/sling/pipes/internal/JsonWriter.java
+++ b/src/main/java/org/apache/sling/pipes/internal/JsonWriter.java
@@ -16,22 +16,26 @@
  */
 package org.apache.sling.pipes.internal;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.Resource;
-import org.apache.sling.pipes.CustomOutputWriter;
+import org.apache.sling.pipes.OutputWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.json.Json;
 import javax.json.JsonValue;
 import javax.json.stream.JsonGenerator;
+import javax.script.ScriptException;
 import java.io.StringWriter;
-import java.io.Writer;
 import java.util.Map;
 
 /**
  * default output writer, that outputs JSON with size and output resources' path
  */
-public class JsonWriter extends CustomOutputWriter {
+public class JsonWriter extends OutputWriter {
+    private static Logger logger = LoggerFactory.getLogger(JsonWriter.class);
 
     protected JsonGenerator jsonWriter;
 
@@ -41,10 +45,6 @@ public class JsonWriter extends CustomOutputWriter {
         setWriter(new StringWriter());
     }
 
-    JsonWriter(Writer writer){
-        setWriter(writer);
-    }
-
     @Override
     public boolean handleRequest(SlingHttpServletRequest request) {
         return request.getRequestPathInfo().getExtension().equals(JSON_EXTENSION);
@@ -71,11 +71,17 @@ public class JsonWriter extends CustomOutputWriter {
             jsonWriter.writeStartObject();
             jsonWriter.write(PATH_KEY, resource.getPath());
             for (Map.Entry<String, Object> entry : customOutputs.entrySet()) {
-                Object o = pipe.getBindings().instantiateObject((String) entry.getValue());
-                if (o instanceof JsonValue) {
-                    jsonWriter.write(entry.getKey(), (JsonValue) o);
-                } else {
-                    jsonWriter.write(entry.getKey(), o.toString());
+                Object o = null;
+                try {
+                    o = pipe.getBindings().instantiateObject((String) entry.getValue());
+                    if (o instanceof JsonValue) {
+                        jsonWriter.write(entry.getKey(), (JsonValue) o);
+                    } else {
+                        jsonWriter.write(entry.getKey(), o.toString());
+                    }
+                } catch (ScriptException e) {
+                    logger.error("unable to write entry {}, will write empty value", entry, e);
+                    jsonWriter.write(StringUtils.EMPTY);
                 }
             }
             jsonWriter.writeEnd();
diff --git a/src/main/java/org/apache/sling/pipes/internal/MovePipe.java b/src/main/java/org/apache/sling/pipes/internal/MovePipe.java
index a55de26..ad61df1 100644
--- a/src/main/java/org/apache/sling/pipes/internal/MovePipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/MovePipe.java
@@ -48,7 +48,7 @@ public class MovePipe extends BasePipe {
     }
 
     @Override
-    public Iterator<Resource> getOutput() {
+    protected Iterator<Resource> computeOutput() throws Exception {
         Iterator<Resource> output = Collections.emptyIterator();
         Resource resource = getInput();
         if (resource != null && resource.adaptTo(Item.class) != null) {
diff --git a/src/main/java/org/apache/sling/pipes/internal/MultiPropertyPipe.java b/src/main/java/org/apache/sling/pipes/internal/MultiPropertyPipe.java
index 6bc6cd0..06bbbf8 100644
--- a/src/main/java/org/apache/sling/pipes/internal/MultiPropertyPipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/MultiPropertyPipe.java
@@ -25,6 +25,7 @@ import org.slf4j.LoggerFactory;
 import javax.jcr.Property;
 import javax.jcr.PropertyType;
 import javax.jcr.Value;
+import javax.script.ScriptException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
@@ -44,7 +45,7 @@ public class MultiPropertyPipe extends BasePipe {
     MVResourceIterator iterator;
 
     @Override
-    public Iterator<Resource> getOutput() {
+    protected Iterator<Resource> computeOutput() throws Exception {
         iterator = new MVResourceIterator(getInput());
         return iterator;
     }
diff --git a/src/main/java/org/apache/sling/pipes/internal/NotPipe.java b/src/main/java/org/apache/sling/pipes/internal/NotPipe.java
index df199cd..18b710a 100644
--- a/src/main/java/org/apache/sling/pipes/internal/NotPipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/NotPipe.java
@@ -36,7 +36,7 @@ public class NotPipe extends ReferencePipe {
     }
 
     @Override
-    public Iterator<Resource> getOutput() {
+    protected Iterator<Resource> computeOutput() throws Exception {
         if (reference.getOutput().hasNext()){
             return EMPTY_ITERATOR;
         }
diff --git a/src/main/java/org/apache/sling/pipes/internal/PackagePipe.java b/src/main/java/org/apache/sling/pipes/internal/PackagePipe.java
index 52d51bc..4214ad2 100644
--- a/src/main/java/org/apache/sling/pipes/internal/PackagePipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/PackagePipe.java
@@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import javax.script.ScriptException;
 import java.io.IOException;
 import java.util.Iterator;
 
@@ -67,20 +68,16 @@ public class PackagePipe extends BasePipe {
     }
 
     @Override
-    public Iterator<Resource> getOutput() {
+    protected Iterator<Resource> computeOutput() throws Exception {
         Iterator<Resource> output = EMPTY_ITERATOR;
-        try {
-            init();
-            if (properties.get(PN_FILTERCOLLECTIONMODE, false)){
-                if (filters == null){
-                    filters = new DefaultWorkspaceFilter();
-                }
-                filters.add(new PathFilterSet(getInput().getPath()));
-                jcrPackage.getDefinition().setFilter(filters, true);
-                output = IteratorUtils.singletonIterator(getInput());
+        init();
+        if (properties.get(PN_FILTERCOLLECTIONMODE, false)){
+            if (filters == null){
+                filters = new DefaultWorkspaceFilter();
             }
-        } catch (IOException | RepositoryException e) {
-            LOGGER.error("unable to deal with package persistence", e);
+            filters.add(new PathFilterSet(getInput().getPath()));
+            jcrPackage.getDefinition().setFilter(filters, true);
+            output = IteratorUtils.singletonIterator(getInput());
         }
         return output;
     }
@@ -91,7 +88,7 @@ public class PackagePipe extends BasePipe {
      * @throws IOException problem with binary
      * @throws RepositoryException problem with package persistence
      */
-    protected void init() throws IOException, RepositoryException {
+    protected void init() throws IOException, RepositoryException, ScriptException {
         if (jcrPackage == null){
             String packagePath = getExpr();
             if (StringUtils.isNotBlank(packagePath)) {
diff --git a/src/main/java/org/apache/sling/pipes/internal/PathPipe.java b/src/main/java/org/apache/sling/pipes/internal/PathPipe.java
index 6e4918c..bbe692d 100644
--- a/src/main/java/org/apache/sling/pipes/internal/PathPipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/PathPipe.java
@@ -24,6 +24,7 @@ import org.apache.sling.pipes.Plumber;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.script.ScriptException;
 import java.util.Collections;
 import java.util.Iterator;
 
@@ -65,7 +66,7 @@ public class PathPipe extends BasePipe {
     }
 
     @Override
-    public Iterator<Resource> getOutput() {
+    protected Iterator<Resource> computeOutput() throws Exception {
         Iterator<Resource> output = Collections.emptyIterator();
         String expression = getExpr();
         try {
diff --git a/src/main/java/org/apache/sling/pipes/internal/PipeBuilderImpl.java b/src/main/java/org/apache/sling/pipes/internal/PipeBuilderImpl.java
index d2b1e81..0dda842 100644
--- a/src/main/java/org/apache/sling/pipes/internal/PipeBuilderImpl.java
+++ b/src/main/java/org/apache/sling/pipes/internal/PipeBuilderImpl.java
@@ -24,8 +24,8 @@ import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.event.jobs.Job;
 import org.apache.sling.pipes.BasePipe;
 import org.apache.sling.pipes.ContainerPipe;
-import org.apache.sling.pipes.CustomOutputWriter;
 import org.apache.sling.pipes.ExecutionResult;
+import org.apache.sling.pipes.OutputWriter;
 import org.apache.sling.pipes.Pipe;
 import org.apache.sling.pipes.PipeBuilder;
 import org.apache.sling.pipes.Plumber;
@@ -353,7 +353,7 @@ public class PipeBuilderImpl implements PipeBuilder {
     public Pipe build(String path) throws PersistenceException {
         Resource pipeResource = persistStep(path, NT_SLING_FOLDER, containerStep);
         if (outputs != null){
-            ResourceUtil.getOrCreateResource(resolver, path + "/" + CustomOutputWriter.PARAM_WRITER, outputs, NT_SLING_FOLDER, false);
+            ResourceUtil.getOrCreateResource(resolver, path + "/" + OutputWriter.PARAM_WRITER, outputs, NT_SLING_FOLDER, false);
         }
         int index = 0;
         for (Step step : steps){
diff --git a/src/main/java/org/apache/sling/pipes/internal/RemovePipe.java b/src/main/java/org/apache/sling/pipes/internal/RemovePipe.java
index df40654..0ed0a6d 100644
--- a/src/main/java/org/apache/sling/pipes/internal/RemovePipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/RemovePipe.java
@@ -55,22 +55,18 @@ public class RemovePipe extends BasePipe {
     }
 
     @Override
-    public Iterator<Resource> getOutput() {
+    protected Iterator<Resource> computeOutput() throws Exception {
         Resource resource = getInput();
         String parentPath = null;
-        try {
-            if (resource.adaptTo(Node.class) != null) {
-                parentPath = removeTree(resource, filter);
-            } else if (resource.adaptTo(Property.class) != null){
-                Property property = resource.adaptTo(Property.class);
-                parentPath = property.getParent().getPath();
-                logger.info("removing property {}", property.getPath());
-                if (!isDryRun()){
-                    property.remove();
-                }
+        if (resource.adaptTo(Node.class) != null) {
+            parentPath = removeTree(resource, filter);
+        } else if (resource.adaptTo(Property.class) != null){
+            Property property = resource.adaptTo(Property.class);
+            parentPath = property.getParent().getPath();
+            logger.info("removing property {}", property.getPath());
+            if (!isDryRun()){
+                property.remove();
             }
-        } catch (RepositoryException e){
-            logger.error("unable to remove current resource {}", resource.getPath(), e);
         }
         if (parentPath != null) {
             return Collections.singleton(resolver.getResource(parentPath)).iterator();
diff --git a/src/main/java/org/apache/sling/pipes/internal/TraversePipe.java b/src/main/java/org/apache/sling/pipes/internal/TraversePipe.java
index e6b1d7d..179325a 100644
--- a/src/main/java/org/apache/sling/pipes/internal/TraversePipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/TraversePipe.java
@@ -52,7 +52,7 @@ public class TraversePipe extends BasePipe {
 
 
     @Override
-    public Iterator<Resource> getOutput() {
+    protected Iterator<Resource> computeOutput() throws Exception {
         return new TraversingIterator(getInput(), getResource().getValueMap());
     }
 
diff --git a/src/main/java/org/apache/sling/pipes/internal/WritePipe.java b/src/main/java/org/apache/sling/pipes/internal/WritePipe.java
index 33da895..3dd749c 100644
--- a/src/main/java/org/apache/sling/pipes/internal/WritePipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/WritePipe.java
@@ -29,6 +29,7 @@ import javax.jcr.Node;
 import javax.jcr.NodeIterator;
 import javax.jcr.Property;
 import javax.jcr.RepositoryException;
+import javax.script.ScriptException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Iterator;
@@ -79,7 +80,7 @@ public class WritePipe extends BasePipe {
      * @param expression configured value to write
      * @return actual value to write to the resource
      */
-    protected Object computeValue(Resource resource, String key, String expression){
+    protected Object computeValue(Resource resource, String key, String expression) throws ScriptException {
         Object value = bindings.instantiateObject((String) expression);
         if (value != null && value instanceof String) {
             //in that case we treat special case like MV or patches
@@ -111,7 +112,7 @@ public class WritePipe extends BasePipe {
      * @param expression configured value to write
      * @return actual value to write to the resource
      */
-    protected Object computeValue(Resource resource, String key, Object expression) {
+    protected Object computeValue(Resource resource, String key, Object expression) throws ScriptException {
         if (expression instanceof String) {
             return computeValue(resource, key, (String)expression);
         } else if (expression instanceof String[]){
@@ -137,7 +138,7 @@ public class WritePipe extends BasePipe {
      * @param target target resource on which configured values will be written
      * @throws RepositoryException issues occuring when traversing nodes
      */
-    private void copyProperties(Resource conf, Resource target) throws RepositoryException {
+    private void copyProperties(Resource conf, Resource target) throws ScriptException {
         ValueMap writeMap = conf.adaptTo(ValueMap.class);
         ModifiableValueMap properties = target.adaptTo(ModifiableValueMap.class);
 
@@ -180,7 +181,7 @@ public class WritePipe extends BasePipe {
      * @param conf configuration JCR tree to write to target resource
      * @param target target resource to write
      */
-    private void writeTree(Node conf, Resource target) throws RepositoryException {
+    private void writeTree(Node conf, Resource target) throws RepositoryException, ScriptException {
         copyProperties(resolver.getResource(conf.getPath()), target);
         NodeIterator childrenConf = conf.getNodes();
         if (childrenConf.hasNext()){
@@ -201,7 +202,7 @@ public class WritePipe extends BasePipe {
 
 
     @Override
-    public Iterator<Resource> getOutput() {
+    protected Iterator<Resource> computeOutput() throws Exception {
         try {
             Resource resource = getInput();
             if (resource != null) {
@@ -217,10 +218,8 @@ public class WritePipe extends BasePipe {
                         }
                     }
                 }
-                return super.getOutput();
+                return super.computeOutput();
             }
-        } catch (Exception e) {
-            logger.error("unable to write values, cutting pipe", e);
         } finally {
             if (propertiesToRemove != null){
                 propertiesToRemove.clear();
diff --git a/src/main/java/org/apache/sling/pipes/internal/XPathPipe.java b/src/main/java/org/apache/sling/pipes/internal/XPathPipe.java
index ccf3420..9b962df 100644
--- a/src/main/java/org/apache/sling/pipes/internal/XPathPipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/XPathPipe.java
@@ -24,6 +24,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.jcr.query.Query;
+import javax.script.ScriptException;
 import java.util.Iterator;
 
 /**
@@ -39,7 +40,7 @@ public class XPathPipe extends BasePipe {
     }
 
     @Override
-    public Iterator<Resource> getOutput() {
+    protected Iterator<Resource> computeOutput() throws Exception {
         String query = getExpr();
         if (StringUtils.isNotBlank(query)){
             logger.info("Executing query: {}", query);
diff --git a/src/main/java/org/apache/sling/pipes/internal/inputstream/CsvPipe.java b/src/main/java/org/apache/sling/pipes/internal/inputstream/CsvPipe.java
index 9d31e7b..3a7bef8 100644
--- a/src/main/java/org/apache/sling/pipes/internal/inputstream/CsvPipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/inputstream/CsvPipe.java
@@ -54,45 +54,40 @@ public class CsvPipe extends AbstractInputStreamPipe {
     }
 
     @Override
-    public Iterator<Resource> getOutput(InputStream inputStream) {
+    public Iterator<Resource> getOutput(InputStream inputStream) throws Exception{
         Iterator<Resource> output = EMPTY_ITERATOR;
         String separator = properties.get(PN_SEPARATOR, DEFAULT_SEPARATOR);
-        try {
-            reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
-            String headersLine = reader.readLine();
-            final String[] headers = headersLine.split(separator);
-            if (headers.length > 0){
-                nextLine = reader.readLine();
-                output = new Iterator<Resource>() {
-                    @Override
-                    public boolean hasNext() {
-                        return StringUtils.isNotBlank(nextLine);
-                    }
-                    @Override
-                    public Resource next() {
-                        try {
-                            String[] values = nextLine.split(separator);
-                            if (values.length < headers.length){
-                                throw new IllegalArgumentException("wrong format line " + index + " should have at least the same number of columns than the headers");
-                            }
-                            Map<String, String> map = new HashMap<>();
-                            for (int i = 0; i < headers.length; i ++){
-                                map.put(headers[i], values[i]);
-                            }
-                            binding = map;
-                            nextLine = reader.readLine();
-                        } catch (Exception e) {
-                            logger.error("Unable to retrieve {}nth line of csv file", index, e);
-                            nextLine = null;
+        reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
+        String headersLine = reader.readLine();
+        final String[] headers = headersLine.split(separator);
+        if (headers.length > 0){
+            nextLine = reader.readLine();
+            final Resource inputResource = getInput();
+            output = new Iterator<Resource>() {
+                @Override
+                public boolean hasNext() {
+                    return StringUtils.isNotBlank(nextLine);
+                }
+                @Override
+                public Resource next() {
+                    try {
+                        String[] values = nextLine.split(separator);
+                        if (values.length < headers.length){
+                            throw new IllegalArgumentException("wrong format line " + index + " should have at least the same number of columns than the headers");
+                        }
+                        Map<String, String> map = new HashMap<>();
+                        for (int i = 0; i < headers.length; i ++){
+                            map.put(headers[i], values[i]);
                         }
-                        return getInput();
+                        binding = map;
+                        nextLine = reader.readLine();
+                    } catch (Exception e) {
+                        logger.error("Unable to retrieve {}nth line of csv file", index, e);
+                        nextLine = null;
                     }
-                };
-            }
-        } catch (IllegalArgumentException iae){
-            logger.error("unable to correctly process csv file", iae);
-        } catch (IOException e){
-            logger.error("unable to process csv file", e);
+                    return inputResource;
+                }
+            };
         }
         return output;
     }
diff --git a/src/main/java/org/apache/sling/pipes/internal/inputstream/JsonPipe.java b/src/main/java/org/apache/sling/pipes/internal/inputstream/JsonPipe.java
index e7862fd..a739b72 100644
--- a/src/main/java/org/apache/sling/pipes/internal/inputstream/JsonPipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/inputstream/JsonPipe.java
@@ -69,56 +69,52 @@ public class JsonPipe extends AbstractInputStreamPipe {
      * @return input resource of the pipe, can be reouputed N times in case output json binding is an array of
      * N element (output binding would be here each time the Nth element of the array)
      */
-    public Iterator<Resource> getOutput(InputStream is) {
+    public Iterator<Resource> getOutput(InputStream is) throws Exception {
         Iterator<Resource> output = EMPTY_ITERATOR;
         Iterator<Resource> inputSingletonIterator = Collections.singleton(getInput()).iterator();
-        String jsonString = null;
-        try {
-            jsonString = IOUtils.toString(is, StandardCharsets.UTF_8);
-            if (StringUtils.isNotBlank(jsonString)) {
-                JsonStructure json;
-                try {
-                    json = JsonUtil.parse(jsonString);
+        String jsonString = IOUtils.toString(is, StandardCharsets.UTF_8);
+        if (StringUtils.isNotBlank(jsonString)) {
+            JsonStructure json;
+            try {
+                json = JsonUtil.parse(jsonString);
 
-                } catch (JsonException ex) {
-                    json = null;
+            } catch (JsonException ex) {
+                json = null;
+            }
+            if (json == null) {
+                binding = jsonString.trim();
+                output = inputSingletonIterator;
+            } else {
+                String valuePath = properties.get(PN_VALUEPATH, String.class);
+                if (StringUtils.isNotBlank(valuePath)){
+                    json = getValue(json, valuePath);
                 }
-                if (json == null) {
-                    binding = jsonString.trim();
+                if (json.getValueType() != ValueType.ARRAY) {
+                    binding = JsonUtil.unbox(json);
                     output = inputSingletonIterator;
                 } else {
-                    String valuePath = properties.get(PN_VALUEPATH, String.class);
-                    if (StringUtils.isNotBlank(valuePath)){
-                        json = getValue(json, valuePath);
-                    }
-                    if (json.getValueType() != ValueType.ARRAY) {
-                        binding = JsonUtil.unbox(json);
-                        output = inputSingletonIterator;
-                    } else {
-                        binding = array = (JsonArray) json;
-                        index = 0;
-                        output = new Iterator<Resource>() {
-                            @Override
-                            public boolean hasNext() {
-                                return index < array.size();
-                            }
+                    binding = array = (JsonArray) json;
+                    index = 0;
+                    final Resource inputResource = getInput();
+                    output = new Iterator<Resource>() {
+                        @Override
+                        public boolean hasNext() {
+                            return index < array.size();
+                        }
 
-                            @Override
-                            public Resource next() {
-                                try {
-                                    binding = JsonUtil.unbox(array.get(index));
-                                } catch (Exception e) {
-                                    logger.error("Unable to retrieve {}nth item of jsonarray", index, e);
-                                }
-                                index++;
-                                return getInput();
+                        @Override
+                        public Resource next() {
+                            try {
+                                binding = JsonUtil.unbox(array.get(index));
+                            } catch (Exception e) {
+                                logger.error("Unable to retrieve {}nth item of jsonarray", index, e);
                             }
-                        };
-                    }
+                            index++;
+                            return inputResource;
+                        }
+                    };
                 }
             }
-        }catch (Exception e) {
-            logger.error("unable to parse JSON {} ", jsonString, e);
         }
         return output;
     }
diff --git a/src/main/java/org/apache/sling/pipes/internal/inputstream/RegexpPipe.java b/src/main/java/org/apache/sling/pipes/internal/inputstream/RegexpPipe.java
index 330a99d..441d26c 100644
--- a/src/main/java/org/apache/sling/pipes/internal/inputstream/RegexpPipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/inputstream/RegexpPipe.java
@@ -23,6 +23,7 @@ import org.apache.sling.pipes.Plumber;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.script.ScriptException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
@@ -63,6 +64,7 @@ public class RegexpPipe extends AbstractInputStreamPipe {
             logger.trace("about to parse {}", text);
             Matcher matcher = pattern.matcher(text);
             if (matcher.find()) {
+                final Resource next = getInput();
                 output = new Iterator<Resource>() {
                     boolean hasNext = true;
                     @Override
@@ -83,11 +85,11 @@ public class RegexpPipe extends AbstractInputStreamPipe {
                             binding = matcher.group(0);
                         }
                         hasNext = matcher.find();
-                        return getInput();
+                        return next;
                     }
                 };
             }
-        } catch (IOException e) {
+        } catch (ScriptException | IOException e) {
             logger.error("unable to open input stream", e);
         }
         return output;
diff --git a/src/main/java/org/apache/sling/pipes/internal/slingquery/AbstractExpressionSlingQueryPipe.java b/src/main/java/org/apache/sling/pipes/internal/slingquery/AbstractExpressionSlingQueryPipe.java
index fd1342a..55d94e2 100644
--- a/src/main/java/org/apache/sling/pipes/internal/slingquery/AbstractExpressionSlingQueryPipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/slingquery/AbstractExpressionSlingQueryPipe.java
@@ -22,6 +22,8 @@ import org.apache.sling.query.SlingQuery;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.script.ScriptException;
+
 /**
  * deals with sling query pipe code that takes an expression as input
  */
@@ -41,8 +43,13 @@ public abstract class AbstractExpressionSlingQueryPipe extends AbstractSlingQuer
 
     @Override
     protected SlingQuery getQuery(Resource resource) {
-        String expression = getExpr();
-        logger.debug("executing sling query pipe with expression {}", expression);
-        return getQuery(resource, expression);
+        try {
+            String expression = getExpr();
+            logger.debug("executing sling query pipe with expression {}", expression);
+            return getQuery(resource, expression);
+        } catch (ScriptException e){
+            logger.error("please check pipe expressions", e);
+        }
+        return null;
     }
 }
diff --git a/src/main/java/org/apache/sling/pipes/internal/slingquery/AbstractSlingQueryPipe.java b/src/main/java/org/apache/sling/pipes/internal/slingquery/AbstractSlingQueryPipe.java
index d80509f..a1cb4ea 100644
--- a/src/main/java/org/apache/sling/pipes/internal/slingquery/AbstractSlingQueryPipe.java
+++ b/src/main/java/org/apache/sling/pipes/internal/slingquery/AbstractSlingQueryPipe.java
@@ -20,13 +20,13 @@ import org.apache.sling.api.resource.Resource;
 import org.apache.sling.pipes.BasePipe;
 import org.apache.sling.pipes.Plumber;
 import org.apache.sling.query.SlingQuery;
-
 import java.util.Iterator;
 
 /**
  * deals with common sling query pipe code
  */
 public abstract class AbstractSlingQueryPipe extends BasePipe {
+
     public AbstractSlingQueryPipe(Plumber plumber, Resource resource) throws Exception {
         super(plumber, resource);
     }
@@ -46,7 +46,7 @@ public abstract class AbstractSlingQueryPipe extends BasePipe {
      * generate outputs out of input resource and abstract query
      * @return output's resource iterator, empty in case input is null
      */
-    public Iterator<Resource> getOutput() {
+    protected Iterator<Resource> computeOutput() throws Exception {
         Resource resource = getInput();
         if (resource != null) {
             SlingQuery query = getQuery(resource);
diff --git a/src/main/java/org/apache/sling/pipes/package-info.java b/src/main/java/org/apache/sling/pipes/package-info.java
index 8528793..8e8c20f 100644
--- a/src/main/java/org/apache/sling/pipes/package-info.java
+++ b/src/main/java/org/apache/sling/pipes/package-info.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("2.1.0")
+@Version("3.0.0")
 package org.apache.sling.pipes;
 
 import org.osgi.annotation.versioning.Version;
diff --git a/src/test/java/org/apache/sling/pipes/internal/PlumberServletTest.java b/src/test/java/org/apache/sling/pipes/internal/PlumberServletTest.java
index fa9564e..4852d6f 100644
--- a/src/test/java/org/apache/sling/pipes/internal/PlumberServletTest.java
+++ b/src/test/java/org/apache/sling/pipes/internal/PlumberServletTest.java
@@ -44,7 +44,6 @@ import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.pipes.AbstractPipeTest;
 import org.apache.sling.pipes.BasePipe;
 import org.apache.sling.pipes.ContainerPipeTest;
-import org.apache.sling.pipes.CustomOutputWriter;
 import org.apache.sling.pipes.OutputWriter;
 import org.junit.Before;
 import org.junit.Test;
@@ -154,7 +153,7 @@ public class PlumberServletTest extends AbstractPipeTest {
         for (int i = 0; i < array.size(); i++) {
             JsonObject object = array.getJsonObject(i);
             assertNotNull("there should be an object returned at each time", object);
-            String path = object.getString(CustomOutputWriter.PATH_KEY);
+            String path = object.getString(OutputWriter.PATH_KEY);
             assertNotNull("the string path should be returned for each item, containing the path of the resource");
             String pathLength = object.getString(pathLengthParam);
             assertNotNull("there should be a pathLength param, as specified in the writer", pathLength);
@@ -211,7 +210,7 @@ public class PlumberServletTest extends AbstractPipeTest {
         when(request.getResource()).thenReturn(resource);
         when(request.getParameter(PlumberServlet.PARAM_PATH)).thenReturn(pathParam);
         when(request.getParameter(PlumberServlet.PARAM_BINDINGS)).thenReturn(bindings);
-        when(request.getParameter(CustomOutputWriter.PARAM_WRITER)).thenReturn(writer);
+        when(request.getParameter(OutputWriter.PARAM_WRITER)).thenReturn(writer);
         when(request.getParameter(BasePipe.DRYRUN_KEY)).thenReturn(dryRun);
         when(request.getParameter(OutputWriter.PARAM_SIZE)).thenReturn(size);
         return request;

-- 
To stop receiving notification emails like this one, please contact
npeltier@apache.org.