Внедрить ResourceInfo, HttpServletRequest в Джерси ExceptionMapper, записанный в i kotlin для AWS -lambda, завершается неудачно - PullRequest
0 голосов
/ 16 апреля 2020

У меня реализован механизм сопоставления исключений для моего 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...