!159 优化 node chain 不存在时候的错误提示

Merge pull request !159 from 与或非/issues/I69VAR
This commit is contained in:
铂赛东
2023-01-20 03:37:57 +00:00
committed by Gitee
3 changed files with 101 additions and 18 deletions

View File

@@ -1,18 +1,42 @@
package com.yomahub.liteflow.builder.el;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.StrUtil;
import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSet;
import com.ql.util.express.exception.QLException;
import com.yomahub.liteflow.builder.el.operator.*;
import com.yomahub.liteflow.builder.el.operator.AnyOperator;
import com.yomahub.liteflow.builder.el.operator.BreakOperator;
import com.yomahub.liteflow.builder.el.operator.DataOperator;
import com.yomahub.liteflow.builder.el.operator.DefaultOperator;
import com.yomahub.liteflow.builder.el.operator.DoOperator;
import com.yomahub.liteflow.builder.el.operator.ElifOperator;
import com.yomahub.liteflow.builder.el.operator.ElseOperator;
import com.yomahub.liteflow.builder.el.operator.FinallyOperator;
import com.yomahub.liteflow.builder.el.operator.ForOperator;
import com.yomahub.liteflow.builder.el.operator.IdOperator;
import com.yomahub.liteflow.builder.el.operator.IfOperator;
import com.yomahub.liteflow.builder.el.operator.IgnoreErrorOperator;
import com.yomahub.liteflow.builder.el.operator.NodeOperator;
import com.yomahub.liteflow.builder.el.operator.PreOperator;
import com.yomahub.liteflow.builder.el.operator.SwitchOperator;
import com.yomahub.liteflow.builder.el.operator.TagOperator;
import com.yomahub.liteflow.builder.el.operator.ThenOperator;
import com.yomahub.liteflow.builder.el.operator.ThreadPoolOperator;
import com.yomahub.liteflow.builder.el.operator.ToOperator;
import com.yomahub.liteflow.builder.el.operator.WhenOperator;
import com.yomahub.liteflow.builder.el.operator.WhileOperator;
import com.yomahub.liteflow.common.ChainConstant;
import com.yomahub.liteflow.exception.DataNofFoundException;
import com.yomahub.liteflow.exception.DataNotFoundException;
import com.yomahub.liteflow.exception.ELParseException;
import com.yomahub.liteflow.exception.FlowSystemException;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.flow.element.Chain;
import com.yomahub.liteflow.flow.element.condition.*;
import com.yomahub.liteflow.flow.element.Node;
import com.yomahub.liteflow.flow.element.condition.Condition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -152,8 +176,10 @@ public class LiteFlowChainELBuilder {
return this;
} catch (QLException e) {
// EL 底层会包装异常,这里是曲线处理
if (Objects.equals(e.getCause().getMessage(), DataNofFoundException.MSG)) {
throw new ELParseException(String.format("[node/chain is not exist or node/chain not register]elStr=%s", elStr));
if (Objects.equals(e.getCause().getMessage(), DataNotFoundException.MSG)) {
// 构建错误信息
String msg = buildDataNotFoundExceptionMsg(elStr);
throw new ELParseException(msg);
}
throw new ELParseException(e.getCause().getMessage());
} catch (Exception e) {
@@ -163,17 +189,18 @@ public class LiteFlowChainELBuilder {
/**
* EL表达式校验
*
* @param elStr EL表达式
* @return true 校验成功 false 校验失败
*/
public static boolean validate(String elStr) {
try {
LiteFlowChainELBuilder.createChain().setEL(elStr);
return Boolean.TRUE;
} catch (ELParseException e) {
LOG.error(e.getMessage());
}
return Boolean.FALSE;
try {
LiteFlowChainELBuilder.createChain().setEL(elStr);
return Boolean.TRUE;
} catch (ELParseException e) {
LOG.error(e.getMessage());
}
return Boolean.FALSE;
}
public void build() {
@@ -184,6 +211,8 @@ public class LiteFlowChainELBuilder {
FlowBus.addChain(this.chain);
}
//#region private method
/**
* build 前简单校验
*/
@@ -196,4 +225,58 @@ public class LiteFlowChainELBuilder {
throw new RuntimeException(CollUtil.join(errorList, ",", "[", "]"));
}
}
/**
* 解析 EL 表达式,查找未定义的 id 并构建错误信息
*
* @param elStr el 表达式
*/
private String buildDataNotFoundExceptionMsg(String elStr) {
String msg = String.format("[node/chain is not exist or node/chain not register]\n EL: %s", StrUtil.trim(elStr));
try {
InstructionSet parseResult = EXPRESS_RUNNER.getInstructionSetFromLocalCache(elStr);
if (parseResult == null) {
return msg;
}
String[] outAttrNames = parseResult.getOutAttrNames();
if (ArrayUtil.isEmpty(outAttrNames)) {
return msg;
}
List<String> chainIds = CollUtil.map(FlowBus.getChainMap().values(), Chain::getChainId, true);
List<String> nodeIds = CollUtil.map(FlowBus.getNodeMap().values(), Node::getId, true);
for (String attrName : outAttrNames) {
if (!chainIds.contains(attrName) && !nodeIds.contains(attrName)) {
msg = String.format("[%s] is not exist or [%s] is not registered, you need to define a node or chain with id [%s] and register it \n EL: ", attrName, attrName, attrName);
// 去除 EL 表达式中的空格和换行符
String sourceEl = StrUtil.removeAll(elStr, CharUtil.SPACE, CharUtil.LF, CharUtil.CR);
// 这里需要注意的是nodeId 和 chainId 可能是关键字的一部分,如果直接 indexOf(attrName) 会出现误判
// 所以需要判断 attrName 前后是否有 ","
int commaRightIndex = sourceEl.indexOf(attrName + StrUtil.COMMA);
if (commaRightIndex != -1) {
// 需要加上 "EL: " 的长度 4再加上 "^" 的长度 1indexOf 从 0 开始,所以还需要加 1
msg = msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaRightIndex + 6, true);
}
int commaLeftIndex = sourceEl.indexOf(StrUtil.COMMA + attrName);
if (commaLeftIndex != -1) {
// 需要加上 "EL: " 的长度 4再加上 "^" 的长度 1再加上 "," 的长度 1indexOf 从 0 开始,所以还需要加 1
msg = msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 7, true);
}
// 还有一种特殊情况,就是 EL 表达式中的节点使用 node("a")
int nodeIndex = sourceEl.indexOf(String.format("node(\"%s\")", attrName));
if (nodeIndex != -1) {
// 需要加上 "EL: " 的长度 4再加上 “node("” 长度 6再加上 "^" 的长度 1indexOf 从 0 开始,所以还需要加 1
msg = msg + sourceEl + "\n" + StrUtil.fill("^", CharUtil.SPACE, commaLeftIndex + 12, true);
}
break;
}
}
} catch (Exception ex) {
// ignore
}
return msg;
}
//#endregion
}

View File

@@ -2,7 +2,7 @@ package com.yomahub.liteflow.builder.el.operator.base;
import cn.hutool.core.util.StrUtil;
import com.ql.util.express.exception.QLException;
import com.yomahub.liteflow.exception.DataNofFoundException;
import com.yomahub.liteflow.exception.DataNotFoundException;
import com.yomahub.liteflow.flow.element.Node;
import java.util.Objects;
@@ -156,7 +156,7 @@ public class OperatorHelper {
public static void checkNodeAndChainExist(Object[] objects) throws QLException {
for (Object object : objects) {
if (Objects.isNull(object)) {
throw new QLException(DataNofFoundException.MSG);
throw new QLException(DataNotFoundException.MSG);
}
}
}

View File

@@ -4,8 +4,8 @@ package com.yomahub.liteflow.exception;
* 未找到数据异常
* @author tangkc
*/
public class DataNofFoundException extends RuntimeException {
public static final String MSG = "DataNofFoundException";
public class DataNotFoundException extends RuntimeException {
public static final String MSG = "DataNotFoundException";
private static final long serialVersionUID = 1L;
@@ -14,11 +14,11 @@ public class DataNofFoundException extends RuntimeException {
*/
private String message;
public DataNofFoundException() {
public DataNotFoundException() {
this.message = MSG;
}
public DataNofFoundException(String message) {
public DataNotFoundException(String message) {
this.message = message;
}