rpc调用无法获取异常信息解决

这篇具有很好参考价值的文章主要介绍了rpc调用无法获取异常信息解决。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

原本http请求的写法如下:
   

private static Executor httpExecutor;

    static {
        // 设置重试策略,自定义,不忽略任何异常(即:任何异常都会重试),参考:DefaultHttpRequestRetryHandler
        HttpRequestRetryHandler retryHandler = (IOException exception, int executionCount, HttpContext context) -> executionCount <= 2;
        HttpClient httpClient = HttpClientBuilder.create().setMaxConnTotal(2000).setMaxConnPerRoute(500).setRetryHandler(retryHandler).build();
        httpExecutor = Executor.newInstance(httpClient);
    }

     /**
     * aisd相关专用,超时时间200s
     * @param body
     * @param headers
     * @param uri
     * @return
     */
    public static String postRequestForAISD(String body, Map<String, String> headers, String uri) {
        log.info("POST {} {}, Headers: {}", uri, body, mapToKeyValue(headers));
        long beginTime = System.currentTimeMillis();
        try {
            Request httpRequest = Request.Post(uri).connectTimeout(50000).socketTimeout(50000).bodyString(body, ContentType.APPLICATION_JSON);
            if (headers != null && headers.size() > 0) {
                headers.forEach(httpRequest::addHeader);
            }
            String result = httpExecutor.execute(httpRequest).returnContent().asString(Consts.UTF_8);
            long endTime = System.currentTimeMillis();
            log.info("POST,uri:{},millis:{},params:{}, Headers: {},result:{}", uri,endTime-beginTime, body, mapToKeyValue(headers), result);
            return result;
        } catch (HttpResponseException e) {
            log.error("POST_HttpResponseException", e);
            throw new RuntimeException("接口调用失败[StatusCode:" + e.getStatusCode() + ", Msg:" + e.getMessage() + "]");
        } catch (IOException e) {
            log.error("POST_IOException", e);
            throw new RuntimeException("接口调用失败[" + e.getMessage() + "]");
        }
    }


上面的调用只能拿到不明确的错误信息,如下:
StatusCode:400, Msg:status code: 400, reason phrase: model_error]

但是直接curl调用外部接口却可以获取详细错误信息,实例如下:
{
  "error": {
    "message": "This model's maximum context length is 8192 tokens. However, you requested 8301 tokens (7277 in the messages, 1024 in the completion). Please reduce the length of the messages or completion.",
    "type": "invalid_request_error",
    "param": "messages",
    "code": "context_length_exceeded"
  }
}

问题:上面的http请求的代码为什么拿不到详细的错误信息?怎么处理才能拿到详细的错误信息?

核心是下面这行代码:
String result = httpExecutor.execute(httpRequest).returnContent().asString(Consts.UTF_8);

httpExecutor.execute(httpRequest)获取到Response,然后调用returnContent方法获取返回内容,
如果rpc请求返回的不是200,那么会抛出HttpResponseException异常,进入catch(HttpResponseException e)分支,抛出RuntimeException异常,提示接口调用失败。如果rpc请求返回的不是200,但是没有抛出HttpResponseException异常,那么会进入catch(IOException e)分支,同样抛出RuntimeException异常,提示接口调用失败。
因此,无论rpc请求返回的是什么状态码,都会抛出RuntimeException异常,导致接口调用失败。但不会获取失败的详情。
解决:修改为先获取returnResponse,然后获取返回实例:
 

  /**
     * aisd相关专用,超时时间200s
     * @param body
     * @param headers
     * @param uri
     * @return
     */
    public static String postRequestForAISD(String body, Map<String, String> headers, String uri) {
        log.info("POST {} {}, Headers: {}", uri, "", mapToKeyValue(headers));
        long beginTime = System.currentTimeMillis();
        try {
            Request httpRequest = Request.Post(uri).connectTimeout(50000).socketTimeout(50000).bodyString(body, ContentType.APPLICATION_JSON);
            if (headers != null && headers.size() > 0) {
                headers.forEach(httpRequest::addHeader);
            }
            Response execute = httpExecutor.execute(httpRequest);
            HttpResponse httpResponse = execute.returnResponse();
            // 获取响应状态码
            int statusCode = httpResponse.getStatusLine().getStatusCode();

            String result = "";
            // 如果响应状态码不是200,则表示请求出错
            if (statusCode != 200) {
                // 获取错误信息
                String errorResponse = EntityUtils.toString(httpResponse.getEntity());
                log.info("errorResponse:"+errorResponse);
                throw new RuntimeException("接口调用失败[StatusCode:" + statusCode + ", Msg:" + errorResponse + "]");
            } else {
                result  = EntityUtils.toString(httpResponse.getEntity());;
            }
            long endTime = System.currentTimeMillis();
            log.info("POST,uri:{},millis:{},params:{}, Headers: {},result:{}", uri,endTime-beginTime, body, mapToKeyValue(headers), result);
            return result;
        } catch (HttpResponseException e) {
            log.error("POST_HttpResponseException", e);
            throw new RuntimeException("接口调用失败[StatusCode:" + e.getStatusCode() + ", Msg:" + e.getMessage() + "]");
        } catch (IOException e) {
            log.error("POST_IOException", e);
            throw new RuntimeException("接口调用失败[" + e.getMessage() + "]");
        }
    }

什么具体场景会让Response的返回内容是空,但HttpResponse的实体不为空呢?能给出具体的实例吗
有以下几种可能的场景:
1. 服务器返回的响应内容为空,这种情况下Response的返回内容是空的,但是HttpResponse的实体可能不为空,因为服务器可能会返回一些响应头信息或者状态码等其他信息。
2. 服务器返回的响应内容格式不正确,这种情况下Response的返回内容是空的,但是HttpResponse的实体可能不为空,因为服务器可能会返回一些错误信息或者其他格式不正确的内容。
3. 网络传输过程中出现异常,这种情况下Response的返回内容是空的,但是HttpResponse的实体可能不为空,因为网络传输过程中可能只传输了部分内容,或者传输过程中出现了错误,但是已经传输的内容仍然可以被获取。
例如,当使用HttpClient发送请求时,如果服务器返回的响应内容为空,但是响应头信息或者状态码不为空,那么Response的返回内容就是空的,但是HttpResponse的实体可能不为空,可以通过调用getEntity方法获取实体。文章来源地址https://www.toymoban.com/news/detail-534159.html

到了这里,关于rpc调用无法获取异常信息解决的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包