getsentry / sentry-android-gradle-plugin

Gradle plugin for Sentry Android. Upload proguard, debug files, and more.

Home Page:https://docs.sentry.io/platforms/android/gradle/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Open for override SentryOkHttpInterceptor.shouldCaptureClientError

kibotu opened this issue · comments

Problem Statement

We do have a lot of custom errors between 400-500 that we don't want to log in specific request.url & response.code situations. currently the SentryOkHttpInterceptor class is not flexible enough to avoid capturing filtered requests which causes a lot of unnecessary noise for us due to tracking expected 'errors'.

Solution Brainstorm

  • one way could be to simply letting developer override the SentryOkHttpInterceptor.shouldCaptureClientError method.
  • another way would be to introduce a filter, e.g.
interface SentryLoggingFilter {

    /**
     * Returning true will not send an api request error to sentry.
     */
    fun ignoreError(requestUrl: String, responseCode: Int): Boolean
}

public open class SentryOkHttpInterceptor(
    private val hub: IHub = HubAdapter.getInstance(),
    private val beforeSpan: BeforeSpanCallback? = null,
    private val captureFailedRequests: Boolean = true,
    private val failedRequestStatusCodes: List<HttpStatusCodeRange> = listOf(
        HttpStatusCodeRange(HttpStatusCodeRange.DEFAULT_MIN, HttpStatusCodeRange.DEFAULT_MAX)
    ),
    private val failedRequestTargets: List<String> = listOf(DEFAULT_PROPAGATION_TARGETS),
    private val errorFilter: List<SentryLoggingFilter>? = null
) : Interceptor {


    private fun shouldCaptureClientError(request: Request, response: Response): Boolean {

        if(errorFilter?.any { it.ignoreError(request.url.toString(), response.code) } == true) {
            return true
        }

        // return if the feature is disabled or its not within the range
        if (!captureFailedRequests || !containsStatusCode(response.code)) {
            return false
        }

        // return if its not a target match
        if (!PropagationTargetsUtils.contain(failedRequestTargets, request.url.toString())) {
            return false
        }

        return true
    }
... 

hi @kibotu, I think beforeSend should actually be sufficient for this (hint contains both okhttp request and response objects):

        SentryAndroid.init(this) {
            it.beforeSend = SentryOptions.BeforeSendCallback { event, hint ->
                val request = hint.get(TypeCheckHint.OKHTTP_REQUEST) as Request
                val response = hint.get(TypeCheckHint.OKHTTP_RESPONSE) as Response
                val url = request.url()
                val statusCode = response.code()
                if (url.encodedPath() == "<my_path>" && statusCode in 400..500) {
                    return@BeforeSendCallback null
                }
                event
            }
        }

does this help?

thanks for the info. yea I can work with that. For us it would be an improvement to have the network logic closer to the requests than at sentry initialisation but it's ok.