2017-08-23 3 views
1
aufgerufen werden

Ich bin vor einem Problem in Play-Framework (2.6) bei dem Versuch, eine Ausnahme zu behandeln, den HttpErrorHandler Mechanismus in einem bestimmten Szenario verwenden.Wiedergabe Rahmen - Fehlerbehandler nicht

Ich habe einen einfachen Fehlerbehandler im Wurzelpaket:

import play.Logger; 
import play.http.HttpErrorHandler; 
import play.mvc.Http; 
import play.mvc.Result; 
import play.mvc.Results; 

import java.util.concurrent.CompletableFuture; 
import java.util.concurrent.CompletionStage; 

public class ErrorHandler implements HttpErrorHandler { 

    @Override 
    public CompletionStage<Result> onClientError(Http.RequestHeader request, int statusCode, String message) { 
     Logger.error("client error"); 
     return CompletableFuture.completedFuture(Results.status(statusCode, "A client error occurred: " + message)); 
    } 

    @Override 
    public CompletionStage<Result> onServerError(Http.RequestHeader request, Throwable exception) { 
     Logger.error("server error"); 

     return CompletableFuture.completedFuture(
       Results.internalServerError("A server error occurred: " + exception.getMessage())); 
    } 
} 

ich eine benutzerdefinierte Steuerung geschaffen, um die Vermögenswerte zu handhaben:

package controllers; 

import org.apache.commons.lang3.StringUtils; 
import play.api.mvc.Action; 
import play.api.mvc.AnyContent; 
import play.mvc.Controller; 

import javax.inject.Inject; 

public class AssetsCustomController extends Controller { 

    private final Assets assets; 

    @Inject 
    public AssetsCustomController(Assets assets) { 
     this.assets = assets; 
    } 

    public Action<AnyContent> at(String path, String file) { 
     if (StringUtils.isEmpty(path)) { 
      throw new IllegalArgumentException(); 
     } 
     return assets.at(path, file, false); 
    } 
} 

ich die Fehlerbehandler überprüft habe und funktioniert für alle Fälle, außer wenn die Ausnahme von dieser Methode in AssetsCu ausgelöst wird stomController:

public Action<AnyContent> at(String path, String file) { 
     if (StringUtils.isEmpty(path)) { 
      throw new IllegalArgumentException(); 
     } 
     return assets.at(path, file, false); 
    } 

Zum Beispiel, wenn die Illegal geworfen wird, meine Fehlerbehandler ignoriert und Wiedergabe nutzt seine nativen Fehlerbehandlung. Hier ist die Stacktrace:

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[IllegalArgumentException: null]] 
     at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:255) 
     at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:182) 
     at play.api.http.DefaultHttpErrorHandler$.onServerError(HttpErrorHandler.scala:286) 
     at play.core.server.Server.logExceptionAndGetResult$1(Server.scala:53) 
     at play.core.server.Server.getHandlerFor(Server.scala:83) 
     at play.core.server.Server.getHandlerFor$(Server.scala:49) 
     at play.core.server.AkkaHttpServer.getHandlerFor(AkkaHttpServer.scala:42) 
     at play.core.server.AkkaHttpServer.getHandler(AkkaHttpServer.scala:215) 
     at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:195) 
     at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$3(AkkaHttpServer.scala:107) 
Caused by: java.lang.IllegalArgumentException: null 
     at controllers.AssetsCustomController.at(AssetsCustomController.java:20) 
     at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$10(Routes.scala:183) 
     at play.core.routing.HandlerInvokerFactory$$anon$6$$anon$7.call(HandlerInvoker.scala:61) 
     at play.core.routing.GeneratedRouter$$anon$2.call(GeneratedRouter.scala:251) 
     at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$9(Routes.scala:183) 
     at play.core.routing.GeneratedRouter.$anonfun$call$5(GeneratedRouter.scala:99) 
     at scala.util.Either.fold(Either.scala:118) 
     at play.core.routing.GeneratedRouter.call(GeneratedRouter.scala:99) 
     at router.Routes$$anonfun$routes$1.applyOrElse(Routes.scala:182) 
     at router.Routes$$anonfun$routes$1.applyOrElse(Routes.scala:154) 

[SOLUTION]
Dank der Antwort Flo354, ich war in der Lage, das Problem zu lösen und die AssetsCustomController ist wie folgt:

package controllers; 

import akka.stream.Materializer; 
import org.springframework.util.StringUtils; 
import play.mvc.Controller; 
import play.mvc.Result; 

import javax.inject.Inject; 
import java.util.concurrent.CompletionStage; 

public class AssetsCustomController extends Controller { 

    private final Assets assets; 
    private final Materializer materializer; 

    @Inject 
    public AssetsCustomController(Materializer materializer, Assets assets) { 
     this.materializer = materializer; 
     this.assets = assets; 
    } 

    public CompletionStage<Result> at(String path, String file) { 
     if (StringUtils.isEmpty(path)) { 
      throw new IllegalArgumentException(); 
     } 
     return assets.at(path, file, false).asJava().apply(request()).run(materializer); 
    } 
} 

Antwort

0

Ihr Action<AnyContent> ist Teil der Scala-API, was bedeutet, dass der Java-Teil nicht verwendet wird.

Ihr benutzerdefinierter Fehlerhandler gilt nur für Java-Quellen. Schauen Sie sich Ihre Stack-Trace

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[IllegalArgumentException: null]] 
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:255) 
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:182) 
    at play.api.http.DefaultHttpErrorHandler$.onServerError(HttpErrorHandler.scala:286) 
.... 

Sie können sehen, dass es scala ist, wenn es play.api.something ist

Sie können dies umgehen, indem Sie zurückschicken eine CompletionStage<Result>

public CompletionStage<Result> test(String path, String file) { 
    if (StringUtils.isEmpty(path)) { 
     throw new IllegalArgumentException(); 
    } 

    return assets.at(path, file, false).asJava().apply(request()).run(materializer); 
} 

Und in Ihrem Controller, nicht vergiss, eine Instanz von akka.stream.Materializer

zu injizieren hoffe, es wird helfen!

+0

Ich konnte den ErrorHandler aufrufen, wenn eine Ausnahme ausgelöst wird. Im Erfolgsfluss wird jedoch der Inhalt in der Konsole statt im Browser gerendert. Dieses Verhalten ist fällig CompletionStage ? Weißt du, wie ich dieses Problem umgehen kann? Folgen Sie einem [Druckbildschirm] (https://snag.gy/fi20zs.jpg), um anzuzeigen, wie der Browser den Anruf behandelt. – vallim

+0

Ich kann das Problem nicht an meinem Ende reproduzieren ... Könnten Sie ein einfaches Git-Projekt bereitstellen, das das Problem reproduziert, damit ich es betrachten kann? – Flo354

+0

Entschuldigung für Verspätung. Ich habe hier nachgesehen und das Problem gefunden. Jetzt funktioniert es gut. Vielen Dank! – vallim

Verwandte Themen