Spring Boot + gRPC Error Handling - Global Exception Handler Using GrpcAdvice

Video
This tutorial is explained in the below Youtube Video.gRPC - Table of Contents
Spring Boot+ gRPC Hello World Example Spring Boot gRPC Server + C# gRPC Client Example Spring Boot 3 + gRPC - Types of gRPC Spring Boot 3 + gRPC Unary Example Spring Boot 3 + gRPC Server Streaming Example Spring Boot 3 + gRPC Client Streaming Example Spring Boot 3 + gRPC Bidirectional Streaming Example Spring Boot + gRPC Deadline Example Spring Boot + gRPC Error Handling Example Spring Boot + gRPC Error Handling - Using Trailer Metadata Spring Boot + gRPC Error Handling - Global Exception Handler Using GrpcAdvice
Implementation
We will be modifying the code we had implemented for Spring Boot gRPC Error Handling Example - Using Trailer Metadata.We create a custom exception handler class named BankAccountAdvice. The BankAccountAdvice class is annotated with @GrpcAdvice which indicates that this class provides advice to the gRPC server for handling exceptions.
The handleAccountNotFoundException method is annotated with @GrpcExceptionHandler for handling the AccountNotFoundException specifically. Within this method, a Metadata object is created to attach additional metadata to the response. A key for a protocol buffer message type DatabaseError is created using ProtoUtils.keyForProto method. This DatabaseError message is then added to the metadata with a customized error message indicating a database error with a specific error type. Finally, a StatusRuntimeException is created with the HTTP status code NOT_FOUND and a description indicating that the requested account number cannot be found. The metadata containing the DatabaseError message is attached to the StatusRuntimeException and returned from the method to inform the client about the error that occurred.
package com.javainuse.bank.service; import com.javainuse.bank.exception.AccountNotFoundException; import com.javainuse.banking.DatabaseError; import io.grpc.Metadata; import io.grpc.Status; import io.grpc.StatusRuntimeException; import io.grpc.protobuf.ProtoUtils; import net.devh.boot.grpc.server.advice.GrpcAdvice; import net.devh.boot.grpc.server.advice.GrpcExceptionHandler; @GrpcAdvice public class BankAccountAdvice { @GrpcExceptionHandler(AccountNotFoundException.class) public StatusRuntimeException handleAccountNotFoundException(AccountNotFoundException accountNotFoundException) { Metadata metadata = new Metadata(); Metadata.Key<DatabaseError> databaseError = ProtoUtils.keyForProto(DatabaseError.getDefaultInstance()); metadata.put(databaseError, DatabaseError.newBuilder().setMessage("Database Error- Connection Refused.") .setErrorType("CONNECTION_REFUSED").build()); var statusRuntimeException = Status.NOT_FOUND.withDescription("The requested Account Number cannot be found.") .asRuntimeException(metadata); return statusRuntimeException; } }