![](/img/trans.png)
[英]What is the proper way to set MDC for logging in grpc-java with ServerInterceptor?
[英]What is the proper way to return an error from gRPC ServerInterceptor
我有一個使用 gRPC 的 Quarkus 應用程序。 我已經實現了一個 ServerInterceptor 來查找和驗證身份驗證令牌。
@ApplicationScoped
public class GrpcAuthInterceptor implements ServerInterceptor {
@Inject
AuthenticationService authenticationService;
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
String token = metadata.get(AuthenticationConstants.AUTH_HEADER_KEY);
Context context = Context.current();
if (!Strings.isNullOrEmpty(token)) {
String fbToken = authenticationService.verifyIdToken(token);
context = context.withValue(AuthenticationConstants.CONTEXT_FB_USER_KEY, fbToken);
} else {
serverCall.close(Status.UNAUTHENTICATED.withDescription("Auth Token Required"), metadata);
}
return Contexts.interceptCall(
context,
serverCall,
metadata,
serverCallHandler);
}
}
這有效並像這樣向客戶端發送消息:
gRPC Error (code: 16, codeName: UNAUTHENTICATED, message: Auth Token Required, details: [], rawResponse: null, trailers: {})
但它在服務器上記錄了這個錯誤,因為我在發送錯誤后沒有從方法中返回:
2022-10-04 21:50:23,006 ERROR [io.qua.mut.run.MutinyInfrastructure] (vert.x-eventloop-thread-0)
Mutiny had to drop the following exception: java.lang.IllegalStateException: call is closed
一些帖子建議我可以像這樣返回一個空的 ServerCall.Listener:
serverCall.close(Status.UNAUTHENTICATED.withDescription("Auth Token Required"), metadata);
return new ServerCall.Listener<ReqT>() {};
這有效並消除了服務器端錯誤消息,但它破壞了返回給客戶端的消息。 客戶只是得到這個:
gRPC Error (code: 2, codeName: UNKNOWN, message: null, details: [], rawResponse: null, trailers: {})
所以我的問題是:如何向客戶端返回有意義的錯誤消息而不在服務器端記錄異常?
您可以在 try 塊中捕獲所有內容並在其中發送消息; 您面臨的問題是您在返回之前先關閉呼叫,因此它會嘗試處理已經關閉的 pipe。
在第二種情況下,當您在“關閉”消息之后立即發送“無效”消息時,詳細消息將被覆蓋。
嘗試類似的東西:
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall, Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler)
{
String token = metadata.get(AuthenticationConstants.AUTH_HEADER_KEY);
Context context = Context.current();
boolean mustClose=false;
try
{
if (!Strings.isNullOrEmpty(token))
{
String fbToken = authenticationService.verifyIdToken(token);
context = context.withValue(AuthenticationConstants.CONTEXT_FB_USER_KEY, fbToken);
return Contexts.interceptCall(context,serverCall,metadata, serverCallHandler);
}
else
{
mustClose=true;
return new ServerCall.Listener<ReqT>() {};
}
}
finally
{
if (mustClose)
serverCall.close(Status.UNAUTHENTICATED.withDescription("Auth Token Required"), metadata);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.