У меня реализован механизм сопоставления исключений для моего AWS -lambda-джерси, я не буду регистрировать некоторые вещи, содержащие метаданные о запросе, принципале принципа, метод / ресурс, вызвавший исключение. так как 405 исключений не включают эту информацию.
Для java Я прочитал, что можно вставить некоторые контексты в модуль отображения исключений, но не могу заставить его работать в kotlin: я пробовал собственный конструктор подход (1 в коде), и я попытался добавить @Context для ресурсов, которые нужно внедрить в преобразователе исключений (2 в коде):
Начинаю сомневаться, что контекст фактически доступен в преобразователе исключений. Любые идеи?
class ExceptionMapper : ExceptionMapper<Throwable> {
// 1. these never get set from the constructor
private var request: HttpServletRequest? = null
private var resourceInfo: ResourceInfo? = null
// 2.
// the below throws an exception
// java.lang.IllegalArgumentException:
// The field field(HttpServletRequest request in com.xyz.cloud.api.jersey.ExceptionMapper)
// may not be static, final or have an Annotation type
//
// @Context private var request: HttpServletRequest? = null
// @Context private var resourceInfo: ResourceInfo? = null
fun ExceptionMapper(@Context resourceInfo: ResourceInfo, @Context request: HttpServletRequest) {
this.resourceInfo = resourceInfo
this.request = request
}
override fun toResponse(exception: Throwable): Response {
createErrorResponse(
status = Response.Status.INTERNAL_SERVER_ERROR,
error = "INTERNAL_SERVER_ERROR",
error_description = exception.message ?: "internal server error",
errorCode = ErrorCodes.UNKNOWN,
exception = exception).also {
val resourceMethod = resourceInfo?.resourceMethod ?: ""
val userId = request?.userPrincipal?.name ?: ""
log.metric(
"jersey-unhandled-exception",
mapOf(
"message" to exception.message,
"trace" to Throwables.getStackTraceAsString(exception),
"cause" to exception.cause.toString(),
"subject" to userId,
"resourceMethod" to resourceMethod.toString()
)
)
}
}
}
RequestStreamHandler регистрирует отображение исключений следующим образом:
val app = ResourceConfig()
.packages(resourcesPackagePrefix)
.register(CORSFilter())
.register(CloudWatchEventFilter())
.register(ContextBinder())
.register(ExceptionMapper())
.registerJsonHandler(moshi)
.register(RequestContextBinder())
val handler = let {
val basePath = jerseyContext.getBasePath()
if (basePath.isNotEmpty()) {
LambdaContainerHandler.getContainerConfig().apply {
serviceBasePath = basePath
isStripBasePath = true
defaultContentCharset = "UTF-8"
}
}
JerseyLambdaContainerHandler.getAwsProxyHandler(app)
}
...
class RequestContextBinder : AbstractBinder() {
override fun configure() {
bindFactory(AwsProxyServletRequestSupplier::class.java)
.to(HttpServletRequest::class.java)
.`in`(RequestScoped::class.java);
bindFactory(AwsProxyServletContextSupplier::class.java)
.to(ServletContext::class.java)
.`in`(RequestScoped::class.java);
}
}