共计 2613 个字符,预计需要花费 7 分钟才能阅读完成。
在零碎中,异样被分为了两种,一种是已知异样,一种是未知异样。
已知异样在框架中被封装为 cn.vte.framework.common.http.InnerExp
,个别为业务异样,能够在任何接口拜访范畴内的代码内抛出。
InnerExp 作用
InnerExp
是为了可能灵便返回信息到前端,当办法的调用过多时或者逻辑嵌套过深,在满足条件时,不必一层一层返回,间接抛出异样即可把信息返回。
配合 GlobalMvcExceptionHandler
应用,该类拦挡了所有的 mvc http 接口异样,任何异样都会被解决成 RequestResult 构造。
InnerExp
特地的是,它会携带两种信息,一个是 RequestResult
还有一个是 Exception
。这让 InnerExp
有更加灵便的性能。
InnerExp
携带 RequestResult
可能让返回的后果更加丰盛,开发人员能够自定义 RequestResult
的内容,甚至与返回失常的后果。
比方当你应用递归调用时,满足条件收集到了足够的信息时,抛出一个异样间接把后果返回,所以异样的应用不齐全是为了告诉程序异样了,灵便应用也可能解决失常的业务。
InnerExp
携带 Exception
时,GlobalMvcExceptionHandler
会判断 cause 是否为空,如果不为空就间接打印堆栈信息,帮忙排查问题,在业务代码遇见异样,并且不想解决时,间接交给最上层去做,有些时候会更加不便。
总结一下 InnerExp
的性能:
- 疾速抛出异样,将信息返回给前台,函数嵌套的状况下不必层层传递信息,并且可能携带实在异样,顶层打印堆栈信息。
- 疾速返回业务信息,同样不必层层传递。
- 继承
Supplier
接口,在流式解决中更加不便抛出异样。 - 利用
ifThr
传入条件判断是否应该抛出异样。
解决其它异样
在已知异样之外,其它异常情况的解决就绝对辣手一些,呈现什么品种的异样是齐全未知的。
你只能在产生某些异样的时候解决。
可能你会问,为什么不间接都当成一种状况解决呢?只有产生异样一律告知外部异样。
这样解决尽管简略,然而很多异样实际上不是后端逻辑谬误引擎的,更多的是数据校验方面的引起的,个别是因为前段发送数据不合乎后端的要求。
此时,你就要解决这种用异样,把他们整顿成前端开发人员,甚至是用户可能看懂的异样。
上面是框架中,所遇见过的一些异样类型解决。
1 ServiceUnavailable
因为 feign 调用不到的产生的异样。
框架会返回” 后盾服务未启动 ”的揭示。
2 HttpMessageNotReadableException
因为前端传入的 json 数据,无奈失常序列化为 java 对象产生的异样。
此异样解决的状况较为简单,因为解决异样自身不重要,更重要的是解决它携带的 cause
。
框架中解决了四种 cause
:
InvalidFormatException
MissingKotlinParameterException
JsonMappingException
- 其它异样
1、2、3,实际上都为 jackson 所抛出的异样。
此处, 又是 jackson 的一大亮点,那就是你可能通过这些异样,来捕捉到 json 序列化的谬误地位。
因为这些异样,都携带有 getPath()
办法,可能找到嵌套的 json 谬误门路,于是框架中利用了这一点,来获取 jackson 序列化谬误的具体字段信息
fun List<JsonMappingException.Reference>.toPath(): String {val sb = StringBuilder()
this.mapIndexed { index, reference ->
sb.append(if (index == 0 || reference.fieldName == null) {reference.fieldName ?: "[${reference.index}]"
} else {".${reference.fieldName}"
}
)
}
return sb.toString()}
举个例子,上面的这段代码,将会输入,a.type
,来告知前端,a
对象下的 type
缺失。
data class A(val name: String, val type: String)
data class B(val name: String, val a: A)
val test = JacksonObject().put("name", "b").put("a", JacksonObject().put("name", "a"))
try {test.convert<B>()
} catch (e: IllegalArgumentException) {
val cause = e.cause
if (cause is MissingKotlinParameterException) {println(cause.path.toPath())
}
}
除了下面的解决 JsonMappingException
还要独自拿进去解决,上面这段代码阐明了解决的思路
is JsonMappingException -> {
val subCause = cause.cause
if (subCause is InnerExp) {
// 产生于 class init 抛出异样
subCause.result
} else if (subCause is DateTimeParseException) {RequestResult.error("""字段"{}"工夫值谬误:"{}"""", cause.path.toPath(), subCause.parsedString)
} else {log.warn("{}", request.requestURI, exception)
RequestResult.error("""字段"{}"值谬误:"{}"""", cause.path.toPath())
}
}
这样解决异样的形式,很显著可能大大减少排查问题的难度。
3 NoHandlerFoundException
当地址找不到产生的异样,如果不解决,将返回 404。
4 MethodArgumentNotValidException
当 spring boot valid 校验失败产生的异样。
框架中,将会获取到校验失败的信息,而后以 RequestResult
的形式返回,缩小前端的解决工作。
如果不解决,前端是无奈获取到谬误的详细信息的,那么校验所能产生的作用就会大打折扣。
本文参加了思否技术征文,欢送正在浏览的你也退出。