None of the answers quite worked for me but they led me in the right direction. See below how I did it in Kotlin.
You can either throw the exceptions in the ErrorInterceptor and catch them in your api call function:
class ErrorInterceptor : Interceptor {
    override fun intercept(chain: Chain): Response {
        val request = chain.request()
        try {
            val response = chain.proceed(request)
            val bodyString = response.body!!.string()
            return response.newBuilder()
                .body(bodyString.toResponseBody(response.body?.contentType()))
                .build()
        } catch (e: Exception) {
            when (e) {
                is SocketTimeoutException -> {
                    throw SocketTimeoutException()
                }
               // Add additional errors... //
            }
        }
    }
Or bundle exceptions with a response object; something like this:
class ErrorInterceptor : Interceptor {
    override fun intercept(chain: Chain): Response {
        val request = chain.request()
        try {
            val response = chain.proceed(request)
            val bodyString = response.body!!.string()
            return response.newBuilder()
                .body(bodyString.toResponseBody(response.body?.contentType()))
                .build()
        } catch (e: Exception) {
            var msg = ""
            val interceptorCode: Int
            when (e) {
                is SocketTimeoutException -> {
                    msg = "Socket timeout error"
                    interceptorCode = 408
                }
               // Add additional errors... //
            }
             return Response.Builder()
                .request(request)
                .protocol(Protocol.HTTP_1_1)
                .code(interceptorCode)
                .message(msg)
                .body("{${e}}".toResponseBody(null)).build()
        }
    }
}
Add the ErrorInterceptor to your okHttpClient:
okHttpClient.newBuilder()
                .addInterceptor(ErrorInterceptor())
                .connectTimeout(10, TimeUnit.SECONDS)
                 // ... //
                .build()
And then something like this in your repository layer:
suspend fun makeAPIRequest(): Resource<ApiResponse> {
        return withContext(ioDispatcher) {
            var response: Response<ApiResponse>? = null
            try {
                response = getResponse()
                // Do additional ops on response here //
            } catch (e: Exception) {
                // Exceptions thrown in ErrorInterceptor will propagate here
            }
        }
    }