2016-05-04 9 views
3

Ich weiß, dass ich möchte, dass die Konsumenten unserer API keine Ausnahme behandeln müssen. Oder vielleicht möchte ich klarstellen, dass die Ausnahme immer protokolliert wird, aber nur der Verbraucher weiß, wie er mit dem Erfolg umgehen soll. Ich will, dass der Klient die Ausnahme auch behandeln kann, wenn sie wollen, gibt es kein gültiges File, dass ich zu ihnen zurückkehren könnte.Getrennte Ausnahmebehandlung einer CompleableFuture

Anmerkung: FileDownload ist ein Supplier<File>

@Override 
public CompletableFuture<File> processDownload(final FileDownload fileDownload) { 
    Objects.requireNonNull(fileDownload); 
    fileDownload.setDirectory(getTmpDirectoryPath()); 
    CompletableFuture<File> future = CompletableFuture.supplyAsync(fileDownload, executorService); 
    future... throwable -> { 
     if (throwable != null) { 
      logError(throwable); 
     } 
     ... 
     return null; // client won't receive file. 
    }); 
    return future; 

} 

ich wirklich die CompletionStage Sachen nicht verstehen. Benutze ich exception oder handle? Bekomme ich die ursprüngliche Zukunft oder die Zukunft, die sie zurückgeben?

+0

Was soll das Ergebnis deiner Zukunft sein, wenn eine Ausnahme ausgelöst wird? Sollte der Verbraucher die Ausnahme noch erhalten, oder möchten Sie, dass er nicht weiß, was passiert ist? – Jeffrey

+0

@ Jeffrey Ich würde erwarten, dass sie die Ausnahme erhalten, behandeln sie auch selbst, wenn sie wollen. Ich erwarte nicht, dass sie eine Datei erhalten – xenoterracide

Antwort

7

Unter der Annahme, dass Sie nicht wollen, das Ergebnis Ihrer CompletableFuture beeinflussen, wollen Sie verwenden CompletableFuture::whenComplete:

future = future.whenComplete((t, ex) -> { 
    if (ex != null) { 
    logException(ex); 
    } 
}); 

Jetzt, wenn der Verbraucher Ihrer API versucht future.get() zu nennen, werden sie eine Ausnahme erhalten , aber sie müssen nicht unbedingt etwas damit anfangen.


Wenn Sie jedoch Ihre Verbraucher in Unkenntnis der Ausnahme behalten möchten (null zurück, wenn die fileDownload ausfällt), können Sie entweder CompletableFuture::handle oder CompletableFuture::exceptionally verwenden:

future = future.handle((t, ex) -> { 
    if (ex != null) { 
    logException(ex); 
    return null; 
    } else { 
    return t; 
    } 
}); 

oder

future = future.exceptionally(ex -> { 
    logException(ex); 
    return null; 
}); 
+3

Es ist viel einfacher. Ein Verbraucher, der gegen Ausnahmen unwissend ist, kann einfach mit "future.thenAccept" verkettet werden. Der entscheidende Punkt hierbei ist, dass der Verbraucher im Ausnahmefall nie aufgerufen wird, so dass er weder eine Ausnahme noch einen "Null" -Wert behandeln muss. Die Quintessenz ist, verwenden Sie nicht 'get()' ... – Holger