diff --git a/data-discovery/src/main/java/search/DbPSearch.java b/data-discovery/src/main/java/search/DbPSearch.java
index 3fdea6fe821db3080b26c1cf46704eb5eeade2c2..f24e38b5a3b65509c38778300601c66817fd3255 100644
--- a/data-discovery/src/main/java/search/DbPSearch.java
+++ b/data-discovery/src/main/java/search/DbPSearch.java
@@ -36,6 +36,7 @@ public class DbPSearch
 
 
    public String[] queryOverlapingPubdid(Coord coord)
+      throws Exception
    {
       LOGGER.fine("trace");
 
@@ -110,8 +111,9 @@ public class DbPSearch
       }
       catch (SQLException se)
       {
-         logSqlExInfo(se);
+         dbError(se);
          // se.printStackTrace();
+         throw new Exception(se.toString());
       }
 
       String[] pubdidArr = pubdidList.toArray(new String[0]);
@@ -152,6 +154,7 @@ public class DbPSearch
 
 
    public FormatResponseFilter.ObsCore[] queryOutputData(String[] pubdidArr, Pos pos)
+      throws Exception
    {
       LOGGER.fine("trace");
 
@@ -241,8 +244,9 @@ public class DbPSearch
       }
       catch (SQLException se)
       {
-         logSqlExInfo(se);
+         dbError(se);
          // se.printStackTrace();
+         throw new Exception(se.toString());
       }
 
       FormatResponseFilter.ObsCore[] cubes = obsCoreList.toArray(new FormatResponseFilter.ObsCore[0]);
@@ -261,7 +265,7 @@ public class DbPSearch
       }
       catch(SQLException se)
       {
-         logSqlExInfo(se);
+         dbError(se);
          return null;
       }
    }
@@ -275,7 +279,7 @@ public class DbPSearch
       }
       catch(SQLException se)
       {
-         logSqlExInfo(se);
+         dbError(se);
          return null;
       }
    }
@@ -289,7 +293,7 @@ public class DbPSearch
       }
       catch(SQLException se)
       {
-         logSqlExInfo(se);
+         dbError(se);
          return null;
       }
    }
@@ -303,7 +307,7 @@ public class DbPSearch
       }
       catch(SQLException se)
       {
-         logSqlExInfo(se);
+         dbError(se);
          return null;
       }
    }
@@ -393,11 +397,11 @@ public class DbPSearch
    }
 
 
-   private void logSqlExInfo(SQLException se)
+   private void dbError(SQLException se)
    {
       LOGGER.fine("SQLState : " + se.getSQLState());
       LOGGER.fine("ErrorCode: " + se.getErrorCode());
-      LOGGER.warning("Message  : " + se.getMessage());
+      LOGGER.warning("Message: " + se.getMessage());
       Throwable t = se.getCause();
       while(t != null) {
          LOGGER.fine("Cause: " + t);
diff --git a/data-discovery/src/main/java/webapi/formatfilter/FormatResponseFilter.java b/data-discovery/src/main/java/webapi/formatfilter/FormatResponseFilter.java
index 20ca749c3f8c4afb7f53ca3b64159cef81aa0ae6..6ccca2dac2bd856dfaef34b31deddf6a7d6e8efa 100644
--- a/data-discovery/src/main/java/webapi/formatfilter/FormatResponseFilter.java
+++ b/data-discovery/src/main/java/webapi/formatfilter/FormatResponseFilter.java
@@ -61,12 +61,6 @@ public class FormatResponseFilter implements Filter
 
    private String reqQueryString;
 
-   protected void doUsageError(String message, PrintWriter printWriter)
-   {
-      printWriter.println("UsageError : " + message);
-   }
-
-
    @Override
    public void init(FilterConfig filterConfig) throws ServletException
    {
@@ -77,78 +71,135 @@ public class FormatResponseFilter implements Filter
       LOGGER.config("DB: " + settings.dbConn.toString());
    }
 
+   // FIXME move error handling funcs to VOlib
+
+   protected void doMultiValuedParamNotSupported(String message, PrintWriter printWriter)
+   {
+      printWriter.println("MultiValuedParamNotSupported : " + message);
+   }
+
+   protected void doUsageError(String message, PrintWriter printWriter)
+   {
+      printWriter.println("UsageError : " + message);
+   }
+
+   protected void doError(String message, PrintWriter printWriter)
+   {
+      printWriter.println("Error : " + message);
+   }
+
+
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
    {
       LOGGER.fine("trace");
       LOGGER.fine("REQUEST START =============================================================================================");
-      long startTime_msec = System.currentTimeMillis();
 
       FormatResponseWrapper responseWrapper = new FormatResponseWrapper((HttpServletResponse) response);
 
-      chain.doFilter(request, responseWrapper);
+      try
+      {
+         long startTime_msec = System.currentTimeMillis();
 
-      String[] pubdidArr = responseWrapper.getPubdidArr();
 
-      if ((pubdidArr != null) && (pubdidArr.length > 0))
-      {
-         PrintWriter responseWriter = ((HttpServletResponse)response).getWriter();
-
-         // VLKB: reconstruct cutout/merge queryStrings and overlap code
-         Map<String, String[]> params = request.getParameterMap();
-         Pos  pos  = Pos.parsePos(params, DEFAULT_SKY_SYSTEM);
-         Band band = Band.parseBand(params, DEFAULT_SPEC_SYSTEM);
-         String queryStringBase = toQueryString(pos, band);
-
-         // VLKB: calc overlap-code for sky
-         ObsCore[] obsCoreArr = queryObsCore(pubdidArr, pos);
-
-         // VLKB: calc overlap-code for velocity
-         // convert overlap-codes and adds access-urls for cutout, merge
-         Dataset[] datasetArr = convert(obsCoreArr, band,
-               settings.serviceUrls.cutoutUrl(),
-               queryStringBase);
-
-         String respFormat;
-         String respFormatReq[] = params.get("RESPONSEFORMAT");
-         if(respFormatReq != null && (respFormatReq.length > 0) && !respFormatReq[0].isEmpty())
+         chain.doFilter(request, responseWrapper);
+
+         String[] pubdidArr = responseWrapper.getPubdidArr();
+
+         if ((pubdidArr != null) && (pubdidArr.length > 0))
          {
-            respFormat = respFormatReq[0];
-            LOGGER.finest("responseFormat(from request): " + respFormat);
+            PrintWriter responseWriter = ((HttpServletResponse)response).getWriter();
+
+            // VLKB: reconstruct cutout/merge queryStrings and overlap code
+            Map<String, String[]> params = request.getParameterMap();
+            Pos  pos  = Pos.parsePos(params, DEFAULT_SKY_SYSTEM);
+            Band band = Band.parseBand(params, DEFAULT_SPEC_SYSTEM);
+            String queryStringBase = toQueryString(pos, band);
+
+            // VLKB: calc overlap-code for sky
+            ObsCore[] obsCoreArr = queryObsCore(pubdidArr, pos);
+
+            // VLKB: calc overlap-code for velocity
+            // convert overlap-codes and adds access-urls for cutout, merge
+            Dataset[] datasetArr = convert(obsCoreArr, band,
+                  settings.serviceUrls.cutoutUrl(),
+                  queryStringBase);
+
+            String respFormat;
+            String respFormatReq[] = params.get("RESPONSEFORMAT");
+            if(respFormatReq != null && (respFormatReq.length > 0) && !respFormatReq[0].isEmpty())
+            {
+               respFormat = respFormatReq[0];
+               LOGGER.finest("responseFormat(from request): " + respFormat);
+            }
+            else
+            {
+               respFormat = settings.serviceUrls.responseFormat();
+               LOGGER.finest("responseFormat(from settings): " + respFormat);
+            }
+
+            response.setCharacterEncoding(RESPONSE_ENCODING);
+
+            if(respFormat.startsWith("application/x-votable+xml"))
+            {
+               response.setContentType("application/xml");
+               boolean showDuration = false;
+
+               XmlSerializer.serializeToVoTable(responseWriter, RESPONSE_ENCODING,
+                     datasetArr,
+                     settings.serviceUrls.cutoutUrl(),settings.serviceUrls.mergeUrl(),
+                     showDuration,startTime_msec);
+            }
+            else
+            {
+               final String errMsg = "Illegal response format request: " + respFormat;
+               LOGGER.warning(errMsg);
+               response.setContentType("text/plain");
+               doUsageError(errMsg, responseWriter);
+               // FIXME set http err code 
+            }
+
+            responseWriter.close();
          }
          else
          {
-            respFormat = settings.serviceUrls.responseFormat();
-            LOGGER.finest("responseFormat(from settings): " + respFormat);
+            LOGGER.fine("SearchServlet returned no ID's.");
          }
+      }
+      catch(MultiValuedParamNotSupported ex)
+      {
+         LOGGER.warning("MultiValuedParamNotSupported: " + ex.getMessage());
 
-         response.setCharacterEncoding(RESPONSE_ENCODING);
+         responseWrapper.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+         responseWrapper.setContentType("text/plain");
 
-         if(respFormat.startsWith("application/x-votable+xml"))
-         {
-            response.setContentType("application/xml");
-            boolean showDuration = false;
+         PrintWriter writer = responseWrapper.getWriter();
+         doMultiValuedParamNotSupported(ex.getMessage(), writer);
+         writer.close();
+      }
+      catch(IllegalArgumentException ex)
+      {
+         LOGGER.warning("IllegalArgumentException: " + ex.getMessage());
 
-            XmlSerializer.serializeToVoTable(responseWriter, RESPONSE_ENCODING,
-                  datasetArr,
-                  settings.serviceUrls.cutoutUrl(),settings.serviceUrls.mergeUrl(),
-                  showDuration,startTime_msec);
-         }
-         else
-         {
-            final String errMsg = "Illegal response format request: " + respFormat;
-            LOGGER.warning(errMsg);
-            response.setContentType("text/plain");
-            doUsageError(errMsg, responseWriter);
-            // FIXME set http err code 
-         }
+         responseWrapper.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+         responseWrapper.setContentType("text/plain");
 
-         responseWriter.close();
+         PrintWriter writer = responseWrapper.getWriter();
+         doUsageError(ex.getMessage(), writer);
+         writer.close();
       }
-      else
+      catch(Exception ex)
       {
-         LOGGER.fine("SearchServlet returned no ID's.");
+         LOGGER.warning("Exception: " + ex.getMessage());
+         // ex.printStackTrace();
+
+         responseWrapper.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+         responseWrapper.setContentType("text/plain");
+
+         PrintWriter writer = responseWrapper.getWriter();
+         doError(ex.toString(), writer);
+         writer.close();
       }
 
       LOGGER.fine("REQUEST END   =============================================================================================");
@@ -216,6 +267,7 @@ public class FormatResponseFilter implements Filter
 
 
    private FormatResponseFilter.ObsCore[] queryObsCore(String[] pubdidArr, Pos pos)//, String fitsRemotePath)
+           throws Exception
    {
       LOGGER.fine("trace");