changeset 449:dc7237d84f8d

When a remote extractor fails, still populate menu with ones that were valid.
author Lucas Thompson <dev@lucas.im>
date Wed, 28 Jun 2017 10:40:36 +0100
parents d2cf357c946b
children 5fbecd666002
files src/app/services/feature-extraction/FeatureExtractionWorker.ts
diffstat 1 files changed, 36 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/app/services/feature-extraction/FeatureExtractionWorker.ts	Wed Jun 28 10:39:23 2017 +0100
+++ b/src/app/services/feature-extraction/FeatureExtractionWorker.ts	Wed Jun 28 10:40:36 2017 +0100
@@ -45,11 +45,33 @@
 
   return tasks.reduce((runningResponses, nextResponse) => {
     return runningResponses.then(response => {
-      return reducer(response, nextResponse());
+      try {
+        return reducer(response, nextResponse());
+      } catch (e) {
+        throw new QueuedTaskFailure(runningResponses);
+      }
     });
   }, Promise.resolve([]));
 }
 
+class QueuedTaskFailure<T> extends Error {
+  public previousResponses: Promise<T[]>;
+
+  constructor(previousResponses: Promise<T[]>, message?: string) {
+    super(message || 'Queued task failed.');
+    this.previousResponses = previousResponses;
+  }
+}
+
+function flattenListResponses(responses: ListResponse[]): ListResponse {
+  return {
+    available: responses.reduce(
+      (flat, res) => flat.concat(res.available),
+      []
+    )
+  };
+}
+
 class AggregateStreamingService implements StreamingService {
   private services: Map<LibraryKey, Factory<PiperStreamingService>>;
 
@@ -71,10 +93,8 @@
     const listThunks: (() => Promise<ListResponse>)[] = [
       ...this.services.values()
     ].map(createClient => () => createClient().list({}));
-
-    return waterfall(listThunks).then(responses => ({
-      available: responses.reduce((flat, res) => flat.concat(res.available), [])
-    }));
+    return waterfall(listThunks)
+      .then(flattenListResponses);
   }
 
   process(request: SimpleRequest): Observable<StreamingResponse> {
@@ -162,6 +182,15 @@
                 method: 'import',
                 result: response
               });
+            })
+            .catch((e) => {
+              console.warn(`${e.message}. Try using results so far`);
+              e.previousResponses.then(responses => {
+                this.workerScope.postMessage({
+                  method: 'import',
+                  result: flattenListResponses(responses)
+                });
+              });
             });
       }
     };
@@ -170,10 +199,10 @@
   private downloadRemoteLibrary(key: LibraryKey,
                                 uri: LibraryUri): Promise<Factory<Service>> {
     return new Promise((res, rej) => {
-      this.requireJs([uri], (plugin) => {
+      this.requireJs([uri], (createModule) => {
         res(() => {
           // TODO a factory with more logic probably belongs in piper-js
-          const lib: any | EmscriptenModule = plugin.createLibrary();
+          const lib: any | EmscriptenModule = createModule();
           const isEmscriptenModule = typeof lib.cwrap === 'function';
           return isEmscriptenModule ? new PiperVampService(lib) : lib; // TODO
         });