aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2022-04-06 09:45:20 +0000
committerHåvard Pettersen <havardpe@oath.com>2022-04-06 09:48:00 +0000
commitddcad206531cc1bf193221653e2a7f07790e5192 (patch)
treeb9a37c736784e496a0ea535fc6626682ac815027 /searchlib
parent5e0741b529762f73286fe0c3c2d3e101b864ba57 (diff)
improve error messages when verifying rank setup
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/fef/resolver/resolver_test.cpp6
-rw-r--r--searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp26
-rw-r--r--searchlib/src/vespa/searchlib/fef/blueprintresolver.h6
-rw-r--r--searchlib/src/vespa/searchlib/fef/verify_feature.cpp4
4 files changed, 37 insertions, 5 deletions
diff --git a/searchlib/src/tests/fef/resolver/resolver_test.cpp b/searchlib/src/tests/fef/resolver/resolver_test.cpp
index 77aba1664ad..536507f3776 100644
--- a/searchlib/src/tests/fef/resolver/resolver_test.cpp
+++ b/searchlib/src/tests/fef/resolver/resolver_test.cpp
@@ -86,4 +86,10 @@ TEST_F("require_that_bad_input_is_handled", Fixture) {
EXPECT_TRUE(dynamic_cast<RankingExpressionBlueprint *>(spec[1].blueprint.get()) != nullptr);
}
+TEST("require that features can be described") {
+ EXPECT_EQUAL(BlueprintResolver::describe_feature("featureName"), vespalib::string("rank feature 'featureName'"));
+ EXPECT_EQUAL(BlueprintResolver::describe_feature("rankingExpression(foo)"), vespalib::string("function 'foo'"));
+ EXPECT_EQUAL(BlueprintResolver::describe_feature("rankingExpression(foo@1234.5678)"), vespalib::string("function 'foo'"));
+}
+
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp b/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp
index 2a12867dd33..731306d1bea 100644
--- a/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp
+++ b/searchlib/src/vespa/searchlib/fef/blueprintresolver.cpp
@@ -28,6 +28,10 @@ constexpr int TRACE_SKIP_POS = 10;
using Accept = Blueprint::AcceptInput;
+vespalib::string describe(const vespalib::string &feature_name) {
+ return BlueprintResolver::describe_feature(feature_name);
+}
+
bool is_compatible(bool is_object, Accept accept_type) {
return ((accept_type == Accept::ANY) ||
((accept_type == Accept::OBJECT) == (is_object)));
@@ -122,7 +126,7 @@ struct Compiler : public Blueprint::DependencyHandler {
should_trace |= (i < TRACE_SKIP_POS);
should_trace |= ((end - pos) < (MAX_TRACE_SIZE - TRACE_SKIP_POS));
if (should_trace) {
- trace += fmt(" ... needed by rank feature '%s'\n", pos->parser.featureName().c_str());
+ trace += fmt(" ... needed by %s\n", describe(pos->parser.featureName()).c_str());
} else if (i == TRACE_SKIP_POS) {
trace += fmt(" (skipped %zu entries)\n", (n - MAX_TRACE_SIZE) + 1);
}
@@ -135,9 +139,9 @@ struct Compiler : public Blueprint::DependencyHandler {
failed_set.insert(feature_name);
auto trace = make_trace(skip_self);
if (trace.empty()) {
- LOG(warning, "invalid rank feature '%s': %s", feature_name.c_str(), reason.c_str());
+ LOG(warning, "invalid %s: %s", describe(feature_name).c_str(), reason.c_str());
} else {
- LOG(warning, "invalid rank feature '%s': %s\n%s", feature_name.c_str(), reason.c_str(), trace.c_str());
+ LOG(warning, "invalid %s: %s\n%s", describe(feature_name).c_str(), reason.c_str(), trace.c_str());
}
}
probe_stack();
@@ -264,6 +268,22 @@ BlueprintResolver::BlueprintResolver(const BlueprintFactory &factory,
{
}
+vespalib::string
+BlueprintResolver::describe_feature(const vespalib::string &name)
+{
+ auto parser = std::make_unique<FeatureNameParser>(name);
+ if (parser->valid() &&
+ (parser->baseName() == "rankingExpression") &&
+ (parser->parameters().size() == 1) &&
+ parser->output().empty())
+ {
+ auto param = parser->parameters()[0];
+ param = param.substr(0, param.find("@"));
+ return fmt("function '%s'", param.c_str());
+ }
+ return fmt("rank feature '%s'", name.c_str());
+}
+
void
BlueprintResolver::addSeed(vespalib::stringref feature)
{
diff --git a/searchlib/src/vespa/searchlib/fef/blueprintresolver.h b/searchlib/src/vespa/searchlib/fef/blueprintresolver.h
index 80320ae780a..3e3b5879518 100644
--- a/searchlib/src/vespa/searchlib/fef/blueprintresolver.h
+++ b/searchlib/src/vespa/searchlib/fef/blueprintresolver.h
@@ -100,6 +100,12 @@ public:
BlueprintResolver(const BlueprintFactory &factory,
const IIndexEnvironment &indexEnv);
+ // Describe a feature based on its name (intended for log messages)
+ //
+ // rankingExpression(foo@hash) -> function 'foo'
+ // feature -> rank feature 'feature'
+ static vespalib::string describe_feature(const vespalib::string &name);
+
/**
* Add a feature name to the list of seeds. During compilation,
* blueprints for all seeds and dependencies will be instantiated
diff --git a/searchlib/src/vespa/searchlib/fef/verify_feature.cpp b/searchlib/src/vespa/searchlib/fef/verify_feature.cpp
index d61d7faef0f..85d1daffd01 100644
--- a/searchlib/src/vespa/searchlib/fef/verify_feature.cpp
+++ b/searchlib/src/vespa/searchlib/fef/verify_feature.cpp
@@ -19,8 +19,8 @@ bool verifyFeature(const BlueprintFactory &factory,
resolver.addSeed(featureName);
bool result = resolver.compile();
if (!result) {
- LOG(error, "rank feature verification failed: %s (%s)",
- featureName.c_str(), desc.c_str());
+ LOG(error, "verification failed: %s (%s)",
+ BlueprintResolver::describe_feature(featureName).c_str(), desc.c_str());
}
return result;
}