1. 概要

このクイック記事では、Nettyでの例外処理について説明します。

簡単に言えば、Nettyは、高性能の非同期およびイベント駆動型ネットワークアプリケーションを構築するためのフレームワークです。 I / O操作は、コールバックメソッドを使用してライフサイクル内で処理されます。

フレームワークとその使用を開始する方法の詳細については、以前の記事を参照してください。

2. Nettyでの例外の処理

先に述べたように、 Nettyはイベント駆動型システムであり、特定のイベントのコールバックメソッドがあります。 例外もそのようなイベントです。

クライアントから受信したデータの処理中またはI/O操作中に例外が発生する可能性があります。 これが発生すると、専用の例外キャッチイベントが発生します。

2.1. 発信元のチャネルでの例外の処理

例外キャッチイベントは、発生すると、 ChannelInboundHandler またはそのアダプターとサブクラスのexceptionsCaught()メソッドによって処理されます。

ChannelHandlerインターフェースではコールバックが非推奨になっていることに注意してください。 現在、ChannelInboudHandlerインターフェースに限定されています。

このメソッドは、ThrowableオブジェクトとChannelHandlerContextオブジェクトをパラメーターとして受け入れます。 Throwable オブジェクトを使用して、スタックトレースを出力したり、ローカライズされたエラーメッセージを取得したりできます。

それでは、チャネルハンドラー ChannelHandlerA を作成し、その exceptionCaught()を実装でオーバーライドしましょう。

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) 
  throws Exception {
 
    logger.info(cause.getLocalizedMessage());
    //do more exception handling
    ctx.close();
}

上記のコードスニペットでは、例外メッセージをログに記録し、 ChannelHandlerContextclose()も呼び出しています。

これにより、サーバーとクライアント間のチャネルが閉じられます。 基本的に、クライアントを切断して終了させます。

2.2. 例外の伝播

前のセクションでは、発生元のチャネルで例外を処理しました。 ただし、実際には、パイプライン内の別のチャネルハンドラーに例外を伝播できます。

エラーメッセージをログに記録してctx.close()を呼び出す代わりに、 ChannelHandlerContext オブジェクトを使用して、別の例外キャッチイベントを手動で発生させます。

これにより、パイプライン内の次のチャネルハンドラーの exceptionCaught()が呼び出されます。

ChannelHandlerA のコードスニペットを変更して、 ctx.fireExceptionCaught()を呼び出してイベントを伝播させましょう。

public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) 
  throws Exception {
 
    logger.info("Exception Occurred in ChannelHandler A");
    ctx.fireExceptionCaught(cause);
}

さらに、別のチャネルハンドラー ChannelHandlerB を作成し、その exceptionCaught()をこの実装でオーバーライドしてみましょう。

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) 
  throws Exception {
 
    logger.info("Exception Handled in ChannelHandler B");
    logger.info(cause.getLocalizedMessage());
    //do more exception handling
    ctx.close();
}

Server クラスでは、チャネルは次の順序でパイプラインに追加されます。

ch.pipeline().addLast(new ChannelHandlerA(), new ChannelHandlerB());

例外がキャッチされたイベントを手動で伝播することは、すべての例外が1つの指定されたチャネルハンドラーによって処理されている場合に役立ちます。

3. 結論

このチュートリアルでは、コールバックメソッドを使用してNettyで例外を処理する方法と、必要に応じて例外を伝播する方法について説明しました。

完全なソースコードは、Githubから入手できます。