当前位置: 首页 > news >正文

WebFlux异常处理:onErrorReturn和onErrorResume

1 缘起

最近在学习WebFlux,
处理异常时遇到些问题,比如,Java直接抛出的异常无法直接被onErrorReturn和onErrorResume捕获,
但是,在map或者flatMap等方法之后的异常又可以直接被捕获,
于是,进行了测试,发现,onErrorReturn和onErrorResume可以捕获的异常是Throwable类型或者Mono或Flux包装的类型。
当我们在使用WebFlux中的onErrorReturn和onErrorResume捕获异常时,有两种方式:
(1)当原生Java运行时异常抛出时,需要使用Mono或Flux包装:Mono.error或FluxError;
(2)在map或者flatMap等其他原生方法中抛出的异常可以直接被捕获,无需包装。
特分享如下,帮助读者轻松应对知识交流与考核。
在这里插入图片描述

2 异常处理

异常处理是软件开发中非常重要的一环,
在业务系统中,我们需要捕获异常,给出合适的描述信息,让调用者清晰这是哪一个环节的异常。
在计算相关的业务中,通常对计算结果有更多的要求,比如,程序内部出现异常后,不能影响计算结果的输出,需要有一个保底的计算结果,比如在广告推荐系统中的广告出价,即使程序内部出现异常,仍要返回最终的广告出价,保证流程可以正常继续往下走。
当然,不同的业务系统有不同的需求,有的需要直接将异常暴露出去,有的需要记录但是给出保底的结果,但是,都要都要对异常进行处理。

2.1 WebFlux异常处理

WebFlux中的异常处理与SpringMVC中的异常处理存在不同的地方,
相同:都可使用全局异常拦截;
不同:WebFlux可以使用自定义的异常处理方法,如onErrorReturn和onErrorResume。
在WebFlux中,onErrorReturn和onErrorResume可以处理的异常是经过Mono或Flux包装的。
可以这样理解:Java直接抛出的运行时异常,onErrorReturn和onErrorResume无法直接捕获,需要通过Mono.error或者Flux.error包装,才能被正常捕获,当然,如果启用了全局异常捕获,则无需包装。
下面看一下onErrorReturn和onErrorResume的源码:

onErrorReturn

在这里插入图片描述

onErrorReusme

在这里插入图片描述

由源码可知,onErrorReturn中调用了onErrorResume,不同的是入参和返回值,onErrorReturn入参是固定值,onErrorResume入参是函数,可以自定义处理逻辑。onErrorResume的参数为Functions<? super Throwable, ? extends Mono>,由这个泛型参数可知,onErrorResume只能处理Throwable类型和Mono及其子类的类型数据,所以,无法直接捕获Java原生运行时异常。Java可抛出异常是Error和Exception的父类,因此,任何运行时异常都不能被onErrorResume或者onErrorReturn捕获,除非使用Mono.error或者Flux.error包装起来,才能正常捕获。
Java异常关系:https://blog.csdn.net/Xin_101/article/details/110210485

2.2 样例

前提条件:未开启全局异常捕获

  • 接口
@GetMapping("/mathematics/operation/flow/mono")@ApiOperation("连续流测试mono")public Mono<Response<Integer>> mathematicsOperationFlowUnderMono(@RequestParam Integer var1, @RequestParam Integer var2) {return mathematicsOperationService.divideMono(var1, var2).onErrorReturn(10).map(addResult -> {logger.info(">>>>>>Add result:{}", addResult);return Response.success(addResult);}).onErrorResume(ex -> {logger.info(">>>>>>Error resume:", ex);return Mono.just(Response.fail(-100));});}

2.2.1 原生运行时异常

Java原生异常即Throwable子类的错误和异常:Error和Exception。
以运行时异常为例,当程序出现异常时,接口返回的结果是WebFlux的信息,而不是开发者自定义的响应模板。

  • 异常处理
    @Overridepublic Mono<Integer> divideMono(Integer var1, Integer var2) {try{return Mono.just(var1 / var2);} catch(Exception ex) {throw new RuntimeException("自定义运行时异常");}}

返回的信息如下:
在这里插入图片描述

2.2.2 Mono包装异常

onErrorReturn和onErrorResume可以处理Mono或Flux包装的异常,
包装如下:

  • 异常处理
    @Overridepublic Mono<Integer> divideMono(Integer var1, Integer var2) {try{return Mono.just(var1 / var2);} catch(Exception ex) {return Mono.error(ex);}}

包装后的异常可以被哦那Error Return捕获,接口中在onErrorReturn中使用了固定数值:10,因此返回的结果是10,结果如下:
在这里插入图片描述

2.2.3 原生Mono异常

由上面可知,WebFlux可以捕获处理Mono或Flux包装的异常信息,
因此,当我们使用map或者flatMap处理数据时,可以直接使用onErrorReturn和onErrorResume捕获异常,map和flatMap中产生的异常会被直接捕获,无需进行包装。
为了测试,我们在map中添加了1/0,运行时会抛出异常,然后在onErrorResume中捕获异常,并返回-100。

    @GetMapping("/mathematics/operation/flow/mono")@ApiOperation("连续流测试mono")public Mono<Response<Integer>> mathematicsOperationFlowUnderMono(@RequestParam Integer var1, @RequestParam Integer var2) {return mathematicsOperationService.divideMono(var1, var2).onErrorReturn(10).onErrorResume(ex -> {logger.info(">>>>>>Error resume -1:", ex);return Mono.just(-1);}).map(addResult -> {logger.info(">>>>>>Add result:{}", addResult);int a = 1/0;return Response.success(addResult);}).onErrorResume(ex -> {logger.info(">>>>>>Error resume:", ex);return Mono.just(Response.fail(-100));});}

当出现异常时,onErrorResume会直接捕获,并返回自定义的数据,如上面的-100,
结果如下图所示。

在这里插入图片描述

3 小结

(1)WebFlux处理异常可以使用onErrorReturn和onErrorResume;
(2)onErrorReturn和onErrorResume可以处理的异常是Throwable类型以及Mono或者Flux及其子类包装的异常;
(3)使用Mono.error和Flux.error包装异常或者在map,flatMap之后处理异常。

相关文章:

WebFlux异常处理:onErrorReturn和onErrorResume

1 缘起 最近在学习WebFlux&#xff0c; 处理异常时遇到些问题&#xff0c;比如&#xff0c;Java直接抛出的异常无法直接被onErrorReturn和onErrorResume捕获&#xff0c; 但是&#xff0c;在map或者flatMap等方法之后的异常又可以直接被捕获&#xff0c; 于是&#xff0c;进行…...

《动手学深度学习 Pytorch版》 4.5 权重衰减

4.5.1 范数与权重衰减 整节理论&#xff0c;详见书本。 4.5.2 高维线性回归 %matplotlib inline import torch from torch import nn from d2l import torch as d2l# 生成一些数据&#xff0c;为了使过拟合效果更明显&#xff0c;将维数增加到 200 并使用一个只包含 20 个样…...

数据脱敏的风险量化评估介绍

1、背景介绍 当前社会信息化高速发展&#xff0c;网络信息共享加速互通&#xff0c;数据呈现出规模大、流传快、类型多以及价值密度低的特点。人们可以很容易地对各类数据实现采集、发布、存储与分析&#xff0c;然而一旦带有敏感信息的数据被攻击者获取将会造成个人隐私的严重…...

SpringCloudGateway网关实战(三)

SpringCloudGateway网关实战&#xff08;三&#xff09; 上一章节我们讲了gateway的内置过滤器Filter&#xff0c;本章节我们来讲讲全局过滤器。 自带全局过滤器 在实现自定义全局过滤器前&#xff0c; spring-cloud-starter-gateway依赖本身就自带一些全局过滤器&#xff0…...

08在MyBatis-Plus中配置多数据源

配置多数据源 模拟多库场景 适用于多种场景: 多库(操作的表分布在不同数据库当中),读写分离(有的数据库负责查询的功能,有的数据库负责增删该的功能),一主多从,混合模式等 第一步: 模拟多库,在mybatis_plus数据库中创建user表,在mybatis_plus_1数据库中创建product表 --创建…...

Centos8安装docker并配置Kali Linux图形化界面

鉴于目前网上没有完整的好用的docker安装kali桌面连接的教程&#xff0c;所以我想做一个。 准备工作 麻了&#xff0c;这服务器供应商提供的镜像是真的纯净&#xff0c;纯净到啥都没有。 问题一&#xff1a;Centos8源有问题 Error: Failed to download metadata for repo ap…...

游戏开发初等数学基础

凑数图() 立体图形面积体积 1. 立方体&#xff08;Cube&#xff09;: 表面积公式: 6 a 2 6a^2 6a2 &#xff08;其中 a a a 是边长&#xff09;。体积公式: a 3 a^3 a3 &#xff08;其中 a a a 是边长&#xff09;。 2. 球体&#xff08;Sphere&#xff09;: 表面积公…...

svg图片代码data:image/svg+xml转png图片方法

把代码保存为html格式的文件中,用浏览器访问,即可右键保存 从AI软件或其它网站得到svg图片代码后,把他复制到下面源码上 注意:src""图片地址中,一些参数的含义 d‘这里是图片代码数据’ viewBox是图片显示区域,宽,高等 fill%23000000’这里表示颜色 ,后面6位0表示黑色…...

解决问题:Replace `‘vue‘;⏎` with `“vue“;`

使用vscode写vue文件的问题&#xff1a; Replace vue;⏎ with "vue"; error Replace v-model:value"xxx"placeholder"inputsearch prettier/prettier 7:38 error Insert ⏎ potentially fixable with the --fix option 原因&#xff1a;格式问题&a…...

ThinkPHP 5.0通过composer升级到5.1,超级简单

事情是这样的&#xff0c;我实现一个验证码登录的功能&#xff0c;但是这个验证码的包提示tp5的版本可以是5.1.1、5.1.2、5.1.3。但我使用的是5.0&#xff0c;既然这样&#xff0c;那就升个级呗&#xff0c;百度了一下&#xff0c;结果发现大部分都是讲先备份application和修改…...

计算机竞赛 多目标跟踪算法 实时检测 - opencv 深度学习 机器视觉

文章目录 0 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习多目标跟踪 …...

一文了解大模型工作原理——以ChatGPT为例

文章目录 写在前面1.Tansformer架构模型2.ChatGPT原理3.提示学习与大模型能力的涌现3.1 提示学习3.2 上下文学习3.3 思维链 4.行业参考建议4.1 拥抱变化4.2 定位清晰4.3 合规可控4.4 经验沉淀 写在前面 2022年11月30日&#xff0c;ChatGPT模型问世后&#xff0c;立刻在全球范围…...

CPP-Templates-2nd--第十九章 萃取的实现 19.7---

目录 19.7 其它的萃取技术 19.7.1 If-Then-Else 19.7.2 探测不抛出异常的操作 19.7.3 萃取的便捷性&#xff08;Traits Convenience&#xff09; 别名模板和萃取&#xff08;Alias Templates And Traits) 变量模板和萃取&#xff08;Variable Templates and Traits&…...

python 采用selenium+cookies 获取登录后的网页

百度网页由于需要登陆手机短信验证。比较麻烦 这里我采用先人工登录百度账号&#xff0c;然后将百度账号的相关cookies保存下来 然后采用selenium动态登录网页 整体代码如下 from selenium import webdriverimport timeoptions webdriver.ChromeOptions()options.add_argu…...

【测试开发】答疑篇 · 什么是软件测试

【测试开发】答疑篇 文章目录 【测试开发】答疑篇1. 生活中的测试2. 什么是软件测试3. 为什么要有测试/没有测试行不行4. 软件测试和软件开发的区别5. 软件测试和软件调试之间的区别6. 软件测试的岗位7. 优秀测试人员具备的素质 【测试开发】答疑篇 软件不一定是桌面应用&#…...

深入解析顺序表:揭开数据结构的奥秘,掌握顺序表的精髓

&#x1f493; 博客主页&#xff1a;江池俊的博客⏩ 收录专栏&#xff1a;数据结构探索&#x1f449;专栏推荐&#xff1a;✅C语言初阶之路 ✅C语言进阶之路&#x1f4bb;代码仓库&#xff1a;江池俊的代码仓库&#x1f525;编译环境&#xff1a;Visual Studio 2022&#x1f38…...

数据风险量化评估方案

一、企业面临数据安全的痛点 1、企业缺少清晰的数据安全意识 各部门重视度不够&#xff0c;缺少主动数据安全管控意识。数据安全管控架构不清晰&#xff0c;职责划分不明确。对数据安全管控认识不全面、不深刻。工作人员对于所持有的数据缺乏概念&#xff0c;导致数据的价值无…...

EasyAVFilter代码示例之将视频点播文件转码成HLS(m3u8+ts)视频点播格式

以下是一套完整的视频点播功能开发源码&#xff0c;就简简单单几行代码&#xff0c;就可以完成原来ffmpeg很复杂的视频点播转码调用流程&#xff0c;而且还可以集成在自己的应用程序中调用&#xff0c;例如java、php、cgo、c、nodejs&#xff0c;不需要再单独一个ffmpeg的进程来…...

day-50 代码随想录算法训练营(19)动态规划 part 11

123.买卖股票的最佳时机||| 分析&#xff1a;只能买卖两次&#xff0c;就是说有五个状态&#xff1a; 没有买过第一次买入第一次卖出第二次买入第二次卖出 思路&#xff1a;二维数组&#xff0c;记录五个状态 1.dp存储&#xff1a;dp[i][1] 第一次买入 dp[i][2] 第一次卖…...

自定义权限指令与防止连点指令

1.权限指令 // 注册一个全局自定义权限指令 v-permission Vue.directive(permission, {inserted: function(el, binding, vnode) {const {value} binding; // 指令传的值// user:edit:phone,sysData:sampleconst permissions [user:edit:address, sysData:entrust, sysData:…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...

React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?

系列回顾&#xff1a; 在上一篇《React核心概念&#xff1a;State是什么&#xff1f;》中&#xff0c;我们学习了如何使用useState让一个组件拥有自己的内部数据&#xff08;State&#xff09;&#xff0c;并通过一个计数器案例&#xff0c;实现了组件的自我更新。这很棒&#…...

SQL注入篇-sqlmap的配置和使用

在之前的皮卡丘靶场第五期SQL注入的内容中我们谈到了sqlmap&#xff0c;但是由于很多朋友看不了解命令行格式&#xff0c;所以是纯手动获取数据库信息的 接下来我们就用sqlmap来进行皮卡丘靶场的sql注入学习&#xff0c;链接&#xff1a;https://wwhc.lanzoue.com/ifJY32ybh6vc…...

中国政务数据安全建设细化及市场需求分析

(基于新《政务数据共享条例》及相关法规) 一、引言 近年来,中国政府高度重视数字政府建设和数据要素市场化配置改革。《政务数据共享条例》(以下简称“《共享条例》”)的发布,与《中华人民共和国数据安全法》(以下简称“《数据安全法》”)、《中华人民共和国个人信息…...