比如有一个查询车辆详情的接口,参数定义的是车牌号,但是我做接口测试可能会传入纯数字、英文、null 等等这些正常参数外的其他字符。 我司返回来的结果直接报 java 错误,在我的理解中如果参数非法,返回的接口应该是提示用户"参数非法"而不是直接报一个 java 错误,不知道对不对。
1
nekoneko 2022-12-26 11:26:30 +08:00
对, 让后端统一处理一下返回信息
|
2
JYii 2022-12-26 11:27:00 +08:00 1
当然是捕捉参数异常丢出去,你同事那直接就是懒得处理
|
3
liprais 2022-12-26 11:27:07 +08:00
直接报 java 错误是抛异常?
抛异常说明有问题,用户不应该看到你内部的异常 |
4
cai88112 2022-12-26 11:27:08 +08:00
你是对的
|
5
InDom 2022-12-26 11:27:23 +08:00
报错误一般就是真的没在入口做检测, 后面莫名其妙在某个地方没按预期运行崩了.
不过入口参数检查的时候,如果不符合预期也可以使用报错的方式反馈. 但是这两种还是可以分出来的 如果 每次都完全不同的错误就属于前者, 如果每次错误提示都很相似, 大概率是第二个了. |
6
k9982874 2022-12-26 11:28:06 +08:00
直接爆堆栈就过分了,让后端加 validation
|
8
wolfie 2022-12-26 11:29:26 +08:00
序列化错误怎么算?
int32 类型,传 abc 。 |
9
yatoooon 2022-12-26 11:29:40 +08:00
后端统一处理
|
10
wong2 2022-12-26 11:29:58 +08:00
400 而非 500
|
11
InDom 2022-12-26 11:30:53 +08:00
但是 如果是后者 属于 预期内的错误, 是可以以可以预期的方式提供错误信息(比如按照接口规范返回与前端沟通过的特定格式的数据)
而非直接给了一个前端不曾预料的返回内容, 所以,不管怎样,如果出现了这个不可预期的返回,就是后端的锅. |
13
dd991 2022-12-26 11:37:12 +08:00
后端提示什么,直接展示出来就好,老板会让他改的
|
14
unco020511 2022-12-26 11:40:10 +08:00
后端有框架可以很方便的校验参数有效性
|
15
AirBai2 2022-12-26 11:43:31 +08:00
http 状态码 400 ,外加 message
|
16
wangritian 2022-12-26 11:46:22 +08:00
你是指报异常吗?确实不对,应该报业务或框架层级的错误
|
17
bthulu 2022-12-26 11:52:56 +08:00
我一般是报 200, 数据返回默认值
|
18
lucays 2022-12-26 12:00:51 +08:00
总之报 500 肯定是有问题
200 还是 4xx 看公司内部规范。。。 |
19
wu00 2022-12-26 12:02:26 +08:00
参数错误,后端 validation+默认提示(给开发人员看的),前端自己也要做前端的 validation ,用户提示信息是前端自己定
业务错误,http 状态码 4xx ,给 errorType 和 message(给开发人员看的),前端根据 errorType 做页面逻辑和错误提示 服务端异常,http 状态码 500 ,前端给友好页面 /提示(稍后再试) |
20
buchikoma 2022-12-26 12:04:24 +08:00
这种需要前后端定一下异常类型和异常提示,后端根据异常类型抛错误信息和 code ,前端根据 code 对错误信息进行包装抛给用户
|
21
xuanbg 2022-12-26 12:49:22 +08:00
直接抛异常那就是懒。嗯嗯,虽然我有时候也这样。
spring 是可以在实体类的字段上通过注解来对参数进行校验的。如果不是实体类,那也可以自己写校验逻辑。然后抛参数非法的异常出去就好了。 虽然,这样做意义其实也不是很大。但作为一个有追求的程序员,优雅是必须的。 |
22
Felldeadbird 2022-12-26 13:32:32 +08:00
按理来说应该提示非法参数。 估计后端没做处理,当非法提交后涉及到异常报错了,触发了 java 错误。
前端的做法应该是根据 code 或者 status 返回结果 执行对应的提示页或错误页。 |
23
hhjswf 2022-12-26 14:19:32 +08:00
说明没有做全局异常处理。
|
24
zypy333 2022-12-26 14:19:44 +08:00
我想起来我的奇葩同事,写个传入楼层返回该楼层门禁点位 list ,然后他硬是写了个如果查不到数据手动抛个异常,但是实际上有的楼层确实是没有门禁报警器的,然后他还不愿意改,最后是前台想办法单独处理,遇到那个楼层,直接不请求后台
|
25
zypy333 2022-12-26 14:30:50 +08:00
他应该不上 v 站
```java public TableDataInfo list(@PathVariable String floor) throws Exception { EntrancePoint entrancePoint=new EntrancePoint(); List<PublicEquipment> listOfep=new ArrayList<>(); List<EntrancePoint> list=null; if(floor.isEmpty()){ throw new Exception("Please enter the number of floors"); }else { entrancePoint.setFloor(floor); list = entrancePointService.selectEntrancePointList(entrancePoint); if(list.isEmpty()){ throw new Exception("The set or list cannot be empty!"); }else{ for (EntrancePoint entrancePoints:list) { PublicEquipment pe =new PublicEquipment(); pe.setDeviceName(entrancePoints.getName()); pe.setIp(entrancePoints.getEntranceHost()); pe.setModelName(entrancePoints.getModelName()); pe.setState(entrancePoints.getEntranceStatus().equals("0")?"开启":"关闭"); pe.setDoorNum(entrancePoints.getVariable()); listOfep.add(pe); } } } return getDataTable(listOfep); } ``` |
26
kop1989smurf 2022-12-26 14:34:49 +08:00
不能任凭异常抛出。
1 、异常需要全局处理,要有对应的类型编号、唯一编号、日志记录。 2 、未处理的异常会增大 web 容器的开销。 3 、不利于其他产品进行统一的错误提示。 |
27
InHello OP @Felldeadbird 对的 就是这样的,但是前端也没有做任何异常处理
|
29
InHello OP @kop1989smurf 我感觉我司他们就没有做任何处理
|
30
YouTing 2022-12-26 15:30:00 +08:00
前后端都没有写校验,也没有抛出异常。前端至少要对 500 等未知错误进行提示,因为不知道什么时候就出奇奇怪怪的的问题,有提示用户就知道这一步不能干,后端的参数校验是必写的
|
31
zoharSoul 2022-12-26 15:32:19 +08:00
如果用户正常操作不会碰见的 case, 那什么文案无所谓的
|
32
Macolor21 2022-12-26 16:00:18 +08:00
spring validation 这么难学吗?
|
33
chioplkijhman 2022-12-26 16:20:15 +08:00
422 Unprocessable Entity
|
34
libook 2022-12-26 16:42:58 +08:00
直接包 Java 错误是不是意味着根本没做错误处理?
具体还是得形成标准,而标准不唯一。主要的目的还是利于联调以及前端进行错误展示,比如对所有的情况划分业务状态码。 |
35
ThreeK 2022-12-26 17:14:42 +08:00
Validation 加 Exception Handling 。自己代码直接参数异常抛出去,项目统一拦截返回,每块代码都各司其职。
|
36
msg7086 2022-12-26 17:40:08 +08:00
抛异常可以但是最顶层要接住异常然后返回正确的 JSON/XML 主体啊。
|
37
zsj1029 2022-12-26 18:52:08 +08:00
@zypy333 我也会这样写,这个习惯个人来看挺好的,但是全局必须有个 catch 拦截,转可读格式数据给前端,我说的是接口的情况。如果是 sdk 调用,调用方处理异常也是可以接受的
|
38
devswork 2022-12-26 20:41:25 +08:00
|
39
devswork 2022-12-26 20:44:25 +08:00
@devswork 我们每个接口都得定义入参 VO ,以及出参 VO ,然后每个 VO 上的每个参数都要加 validation 判断 null 、判断空字符串、判断长度等,必要时候加正则校验,然后写一个统一异常处理器,处理 BindException 、MethodArgumentNotValidException 、ConstraintViolationException ,如果异常是属于业务上定义的,自己封装一个 Exception 和定义一个返回码,用来表示数据不符合业务规定。
|
41
Seayon 2022-12-26 22:28:33 +08:00
基于 Spring 和 Hibernate Validation 的全局参数统一校验,Spring Boot 参数校验
https://blog.csdn.net/Seayonzhao/article/details/118419116 |
42
nanjingwuyanzu 2022-12-26 23:05:11 +08:00 via iPhone
后端这也太懒了吧
|
44
netabare 2022-12-27 08:29:29 +08:00 via Android 1
感觉应该区分「输入 /输出数据不合法」和「程序内部状态错误」吧。
在我的理解里,一个程序应该是只对特定的输入有效,产生期待中的输出,对于这以外的其他输入,应该直接拒绝运行,避免产生意想不到的结果。 在后端里面,这个逻辑应该可以等价于……一个大的事件循环在监听外部的请求,首先检测请求的有效性,对于有效的请求,开始执行这个程序(启动线程、调用服务之类的), |
45
netabare 2022-12-27 08:33:03 +08:00 via Android 1
如果请求内容无效,直接返回错误报告。
然后…在后端程序里面,毕竟无法保证程序状态永远正确,所以需要用异常来检查和保证程序尽量正确运行。 唔,我倒是没怎么写过后端,但是我对程序的理解是这样。感觉重要的还是如何保证请求的内容健康有效这一个环节,当然可用的工具也很多就是了。 至于随地抛异常,我是反对的,因为异常意味着程序状态发生了不正常的情况,即使可以在上层捕获,这种用法给人的感觉就像用异常处理 NPE 一样( |
46
dengji85 2022-12-27 08:59:19 +08:00
我就不做后端校验的,只做前端校验,因为时间不够,能用就行
|
47
wupher 2022-12-27 10:41:11 +08:00
你的理解没错。
后端永远不应依赖于前端校验。正则表达式校验一下车牌号,如果不会写,还可以询问 ChatGpt 。 像这样写代码,能用。但一旦到了运营环境中,出现故障想要溯源,日志中到处都是异常栈,会很难追溯。 |
48
shm7 2022-12-27 10:45:24 +08:00
抛出特定类型的参数非法错误,外部错误处理机制返回 参数非法提示信息。
|
49
daliusu 2022-12-27 11:07:59 +08:00
肯定也不能直接抛出内部错误
可以约定抛出一个 400 错误,携带一个 errorMsg:"xxxx",然后再带个参数来描述需不需要前端弹出提示,比如 talkError:true ,这样前端在接口响应层直接拦截就可以自己写错误提示样式,具体错误信息后端返回,框架一般都自带这种功能 |
52
hellojukay 2022-12-28 14:24:00 +08:00
直接返回 4xx , 但是不要直接提示 "xxx 参数不合法“,对于系统入侵者来说,这样的提示是一个指示牌,告诉他们怎么入侵系统。
|
53
ma836323493 2022-12-28 15:47:22 +08:00
前端都不做校验我后端做什么校验
|
54
SACKJJKLL 2022-12-29 16:00:14 +08:00
参数后端校验,后端写个 wrapper 抛出或者直接 java 抛异常
|