15
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS Lambda JavaでLambdaFunctionで発生した例外の処理について

Last updated at Posted at 2016-02-19

#はじめに
AWS Lambdaで、呼び出し元/呼び出し先ともにJavaを使った際の例外処理についてまとめてみました。

#テスト用のクラス
##Lambda Functionクラス
AWS Lambdaに登録するためのクラスです。

package lambdatest;

import java.time.LocalDateTime;

import com.amazonaws.services.lambda.runtime.Context;

public class Lambda {

	public String ok(Object o, Context context) {
		context.getLogger().log("OK " + LocalDateTime.now());
		return "OK";
	}

	public String timeout(Object o, Context context) {
		try{
			Thread.sleep(TimeUnit.SECONDS.toMillis(100));
		}catch(Exception e){
			
		}
		context.getLogger().log("Timeout " + LocalDateTime.now());
		return "Timeout";
	}

	public String runtimeException(Object o, Context context) {
		context.getLogger().log("RuntimeException " + LocalDateTime.now());
		throw new RuntimeException("RuntimeException");
	}

	public String exception(Object o, Context context) throws Exception {
		context.getLogger().log("exception " + LocalDateTime.now());
		throw new Exception("Exception");
	}
}

##Lambdaの呼び出しコード
登録したLambdaを呼び出すクライアントクラスです。

package lambdatest;

import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.lambda.AWSLambdaClient;
import com.amazonaws.services.lambda.model.InvokeRequest;
import com.amazonaws.services.lambda.model.InvokeResult;

public class InvokeLambda {

	public static void main(String[] args) {
		AWSLambdaClient lambda = new AWSLambdaClient();
		lambda.setRegion(Region.getRegion(Regions.AP_NORTHEAST_1));
		InvokeRequest req = new InvokeRequest();
		req.setFunctionName("LambdaTest");
		req.setPayload("{\"hoo\":\"bar\"}");
		try {
			InvokeResult invoke = lambda.invoke(req);
			String res = new String(invoke.getPayload().array());
			System.out.println(res);
			System.out.println(invoke.getFunctionError());
			System.out.println(invoke.getStatusCode());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

#呼び出し時の挙動確認
上記のテストクラスを使って、呼び出すLambdaのメソッドごとの挙動を確認した結果が以下となります。

##OKのパターン
正常パターン。lambdatest.Lambda::ok を呼び出す。処理は成功して、"OK"という文字列が返って来ます。

Payload:"OK"
FunctionError:null
StatusCode:200

##Timeoutのパターン
lambdatest.Lambda::timeoutを呼び出すと処理がタイムアウトする。
呼び出し元では例外は発生せず、タイムアウト時に以下のPayload,FunctionError,StatusCodeが返ってきます。

Payload:{"errorMessage":"2016-02-19T10:10:00.159Z e59b6744-d6f0-11e5-9eae-c56145704801 Task timed out after 15.00 seconds"}
FunctionError:Unhandled
StatusCode:200

##RuntimeExceptionのパターン
lambdatest.Lambda::runtimeExceptionを呼び出すとRuntimeExceptionがすろーされる。
呼び出し元では例外は発生せず、タイムアウト時に以下のPayload,FunctionError,StatusCodeが返ってきます。

Payload:{"errorMessage":"RuntimeException","errorType":"java.lang.RuntimeException","stackTrace":["lambdatest.Lambda.runtimeException(Lambda.java:28)","sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)","sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)","sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)","java.lang.reflect.Method.invoke(Method.java:497)"]}
FunctionError:Unhandled
StatusCode:200

##Exceptionのパターン
Payloadに入っている例外クラス名がExceptionとなっていだけで、あとはRuntimeExceptionと同じです。

##LambdaのHandler設定が間違っていた時
AWS LambdaのHandler設定が誤っており、呼び出し先クラスやメソッドがない場合。
この場合でも呼び出し元では例外は発生せず、タイムアウト時に以下のPayload,FunctionError,StatusCodeが返ってきます。

Payload:{"errorMessage":"No public method named ERRORHANDLER with appropriate method signature found on class class lambdatest.Lambda"}
FunctionError:Unhandled
StatusCode:200

##例外処理の方法
結論として、AWSクレデンシャル/リージョン/FunctionNameが正しければ、Lambda側で例外が発生してもクライアント側では例外がスローされないため、InvokeResultの中身を見て、エラーかどうかを判断する必要があります。
InvokeResult#getFunctionError()の戻り値がnullでない場合はエラーが発生しているとみなしてもよさそうなので、この場合はPayloadからエラー内容を取り出し、適宜メッセージを取り出してログを吐いたりリトライする形になります。

なおAWSクレデンシャル間違いの場合はcom.amazonaws.AmazonServiceException、リージョンやFunctionNameが違う場合はcom.amazonaws.services.lambda.model.ResourceNotFoundExceptionが発生するため、これは別途catchして例外処理を行う必要があります。

15
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?