Skip to content

Commit 86d8c5a

Browse files
vitstnblinkov
authored andcommitted
YQL-19593 better error handling for Udf
commit_hash:216229b0558e1004453dedddbec8b767b2dab9c6
1 parent 21f509e commit 86d8c5a

File tree

2 files changed

+65
-16
lines changed

2 files changed

+65
-16
lines changed

yql/essentials/minikql/comp_nodes/mkql_udf.cpp

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ namespace NMiniKQL {
1515

1616
namespace {
1717

18+
constexpr size_t TypeDiffLimit = 1000;
19+
20+
TString TruncateTypeDiff(const TString& s) {
21+
if (s.size() < TypeDiffLimit) {
22+
return s;
23+
}
24+
25+
return s.substr(0,TypeDiffLimit) + "...";
26+
}
27+
1828
template<class TValidatePolicy, class TValidateMode>
1929
class TSimpleUdfWrapper: public TMutableComputationNode<TSimpleUdfWrapper<TValidatePolicy,TValidateMode>> {
2030
using TBaseComputation = TMutableComputationNode<TSimpleUdfWrapper<TValidatePolicy,TValidateMode>>;
@@ -43,8 +53,15 @@ using TBaseComputation = TMutableComputationNode<TSimpleUdfWrapper<TValidatePoli
4353
ctx.TypeEnv, ctx.TypeInfoHelper, ctx.CountersProvider, FunctionName, UserType->IsVoid() ? nullptr : UserType,
4454
TypeConfig, flags, Pos, ctx.SecureParamsProvider, &funcInfo);
4555

46-
MKQL_ENSURE(status.IsOk(), status.GetError());
47-
MKQL_ENSURE(funcInfo.Implementation, "UDF implementation is not set for function " << FunctionName);
56+
if (!status.IsOk()) {
57+
UdfTerminate((TStringBuilder() << Pos << " Failed to find UDF function " << FunctionName << ", reason: "
58+
<< status.GetError()).c_str());
59+
}
60+
61+
if (!funcInfo.Implementation) {
62+
UdfTerminate((TStringBuilder() << Pos << " UDF implementation is not set for function " << FunctionName).c_str());
63+
}
64+
4865
NUdf::TUnboxedValue udf(NUdf::TUnboxedValuePod(funcInfo.Implementation.Release()));
4966
TValidate<TValidatePolicy,TValidateMode>::WrapCallable(CallableType, udf, TStringBuilder() << "FunctionWithConfig<" << FunctionName << ">");
5067
return udf.Release();
@@ -190,13 +207,19 @@ using TBaseComputation = TMutableCodegeneratorPtrNode<TUdfWrapper<TValidatePolic
190207
ctx.TypeEnv, ctx.TypeInfoHelper, ctx.CountersProvider, FunctionName, UserType->IsVoid() ? nullptr : UserType,
191208
TypeConfig, flags, Pos, ctx.SecureParamsProvider, &funcInfo);
192209

193-
MKQL_ENSURE(status.IsOk(), status.GetError());
194-
MKQL_ENSURE(funcInfo.Implementation, "UDF implementation is not set for function " << FunctionName);
210+
if (!status.IsOk()) {
211+
UdfTerminate((TStringBuilder() << Pos << " Failed to find UDF function " << FunctionName << ", reason: "
212+
<< status.GetError()).c_str());
213+
}
214+
215+
if (!funcInfo.Implementation) {
216+
UdfTerminate((TStringBuilder() << Pos << " UDF implementation is not set for function " << FunctionName).c_str());
217+
}
218+
195219
udf = NUdf::TUnboxedValuePod(funcInfo.Implementation.Release());
196220
}
197221

198222
void Wrap(NUdf::TUnboxedValue& callable) const {
199-
MKQL_ENSURE(bool(callable), "Returned empty value in function: " << FunctionName);
200223
TValidate<TValidatePolicy,TValidateMode>::WrapCallable(CallableType, callable, TStringBuilder() << "FunctionWithConfig<" << FunctionName << ">");
201224
}
202225

@@ -270,16 +293,27 @@ IComputationNode* WrapUdf(TCallable& callable, const TComputationNodeFactoryCont
270293
ctx.Env, ctx.TypeInfoHelper, ctx.CountersProvider, funcName, userType->IsVoid() ? nullptr : userType,
271294
typeConfig, flags, pos, ctx.SecureParamsProvider, &funcInfo);
272295

273-
MKQL_ENSURE(status.IsOk(), status.GetError());
274-
MKQL_ENSURE(funcInfo.FunctionType->IsConvertableTo(*callable.GetType()->GetReturnType(), true),
275-
"Function '" << funcName << "' type mismatch, expected return type: " << PrintNode(callable.GetType()->GetReturnType(), true) <<
276-
", actual:" << PrintNode(funcInfo.FunctionType, true));
277-
MKQL_ENSURE(funcInfo.Implementation, "UDF implementation is not set for function " << funcName);
296+
if (!status.IsOk()) {
297+
UdfTerminate((TStringBuilder() << pos << " Failed to find UDF function " << funcName << ", reason: "
298+
<< status.GetError()).c_str());
299+
}
300+
301+
if (!funcInfo.FunctionType->IsConvertableTo(*callable.GetType()->GetReturnType(), true)) {
302+
TString diff = TStringBuilder() << "type mismatch, expected return type: " << PrintNode(callable.GetType()->GetReturnType(), true) <<
303+
", actual:" << PrintNode(funcInfo.FunctionType, true);
304+
UdfTerminate((TStringBuilder() << pos << " UDF Function '" << funcName << "' " << TruncateTypeDiff(diff)).c_str());
305+
}
306+
307+
if (!funcInfo.Implementation) {
308+
UdfTerminate((TStringBuilder() << pos << " UDF implementation is not set for function " << funcName).c_str());
309+
}
278310

279311
const auto runConfigType = funcInfo.RunConfigType;
280-
const bool typesMatch = runConfigType->IsSameType(*runCfgNode.GetStaticType());
281-
MKQL_ENSURE(typesMatch, "RunConfig '" << funcName << "' type mismatch, expected: " << PrintNode(runCfgNode.GetStaticType(), true) <<
282-
", actual: " << PrintNode(runConfigType, true));
312+
if (!runConfigType->IsSameType(*runCfgNode.GetStaticType())) {
313+
TString diff = TStringBuilder() << "run config type mismatch, expected: " << PrintNode(runCfgNode.GetStaticType(), true) <<
314+
", actual:" << PrintNode(runConfigType, true);
315+
UdfTerminate((TStringBuilder() << pos << " UDF Function '" << funcName << "' " << TruncateTypeDiff(diff)).c_str());
316+
}
283317

284318
if (runConfigType->IsVoid()) {
285319
if (ctx.ValidateMode == NUdf::EValidateMode::None && funcInfo.ModuleIR && funcInfo.IRFunctionName) {
@@ -320,10 +354,20 @@ IComputationNode* WrapScriptUdf(TCallable& callable, const TComputationNodeFacto
320354
const auto status = ctx.FunctionRegistry.FindFunctionTypeInfo(
321355
ctx.Env, ctx.TypeInfoHelper, ctx.CountersProvider, funcName, userType,
322356
typeConfig, flags, pos, ctx.SecureParamsProvider, &funcInfo);
323-
MKQL_ENSURE(status.IsOk(), status.GetError());
324-
MKQL_ENSURE(funcInfo.Implementation, "UDF implementation is not set");
325357

326-
MKQL_ENSURE(!funcInfo.FunctionType, "Function type info is exist for same kind script, it's better use it");
358+
if (!status.IsOk()) {
359+
UdfTerminate((TStringBuilder() << pos << " Failed to find UDF function " << funcName << ", reason: "
360+
<< status.GetError()).c_str());
361+
}
362+
363+
if (!funcInfo.Implementation) {
364+
UdfTerminate((TStringBuilder() << pos << " UDF implementation is not set for function " << funcName).c_str());
365+
}
366+
367+
if (funcInfo.FunctionType) {
368+
UdfTerminate((TStringBuilder() << pos << " UDF function type exists for function " << funcName).c_str());
369+
}
370+
327371
const auto callableType = callable.GetType();
328372
MKQL_ENSURE(callableType->GetKind() == TType::EKind::Callable, "Expected callable type in callable type info");
329373
const auto callableResultType = callableType->GetReturnType();

yql/essentials/minikql/computation/mkql_computation_node_graph.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ class TPatternNodes: public TAtomicRefCount<TPatternNodes> {
164164
}
165165
}
166166

167+
ITerminator& GetTerminator() {
168+
return *ValueBuilder;
169+
}
170+
167171
const TComputationMutables& GetMutables() const {
168172
return Mutables;
169173
}
@@ -994,6 +998,7 @@ TIntrusivePtr<TComputationPatternImpl> MakeComputationPatternImpl(TExploringNode
994998
depScanner.Walk(root.GetNode(), opts.Env);
995999

9961000
auto builder = MakeHolder<TComputationGraphBuildingVisitor>(opts);
1001+
const TBindTerminator bind(&builder->GetPatternNodes()->GetTerminator());
9971002
for (const auto& node : explorer.GetNodes()) {
9981003
Y_ABORT_UNLESS(node->GetCookie() <= IS_NODE_REACHABLE, "TNode graph should not be reused");
9991004
if (node->GetCookie() == IS_NODE_REACHABLE) {

0 commit comments

Comments
 (0)