-
-
Notifications
You must be signed in to change notification settings - Fork 335
Fix unhelpful error messages in aggregate jobs. #825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -442,45 +442,65 @@ int main(int argc, char * * argv) | |
| for (auto i = state->jobs.begin(); i != state->jobs.end(); ++i) { | ||
| auto jobName = i.key(); | ||
| auto & job = i.value(); | ||
| // For the error message | ||
| std::string lastTriedJobName = i.key(); | ||
|
|
||
| auto named = job.find("namedConstituents"); | ||
| if (named == job.end()) continue; | ||
|
|
||
| if (myArgs.dryRun) { | ||
| for (std::string jobName2 : *named) { | ||
| auto job2 = state->jobs.find(jobName2); | ||
| if (job2 == state->jobs.end()) | ||
| throw Error("aggregate job '%s' references non-existent job '%s'", jobName, jobName2); | ||
| std::string drvPath2 = (*job2)["drvPath"]; | ||
| job["constituents"].push_back(drvPath2); | ||
| } | ||
| } else { | ||
| auto drvPath = store->parseStorePath((std::string) job["drvPath"]); | ||
| auto drv = store->readDerivation(drvPath); | ||
|
|
||
| for (std::string jobName2 : *named) { | ||
| auto job2 = state->jobs.find(jobName2); | ||
| if (job2 == state->jobs.end()) | ||
| throw Error("aggregate job '%s' references non-existent job '%s'", jobName, jobName2); | ||
| auto drvPath2 = store->parseStorePath((std::string) (*job2)["drvPath"]); | ||
| auto drv2 = store->readDerivation(drvPath2); | ||
| job["constituents"].push_back(store->printStorePath(drvPath2)); | ||
| drv.inputDrvs[drvPath2] = {drv2.outputs.begin()->first}; | ||
| } | ||
| try { | ||
| if (myArgs.dryRun) { | ||
| for (std::string jobName2 : *named) { | ||
| lastTriedJobName = jobName2; | ||
| auto job2 = state->jobs.find(jobName2); | ||
| if (job2 == state->jobs.end()) | ||
| throw Error("aggregate job '%s' references non-existent job '%s'", jobName, jobName2); | ||
| std::string drvPath2 = (*job2)["drvPath"]; | ||
| job["constituents"].push_back(drvPath2); | ||
| } | ||
| } else { | ||
| auto drvPath = store->parseStorePath((std::string) job["drvPath"]); | ||
| auto drv = store->readDerivation(drvPath); | ||
|
|
||
| for (std::string jobName2 : *named) { | ||
| lastTriedJobName = jobName2; | ||
| auto job2 = state->jobs.find(jobName2); | ||
| if (job2 == state->jobs.end()) | ||
| throw Error("aggregate job '%s' references non-existent job '%s'", jobName, jobName2); | ||
|
|
||
| if ((*job2).find("error") != (*job2).end()) { | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needing to dereference here tripped me up. I get that this comes from
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Honestly, this is probably fine? I'd probably replace the |
||
| if (job.find("error") == job.end()) { | ||
| job["error"] = fmt("Errors aggregating aggregate job '%1%'.\n", jobName); | ||
| } | ||
|
Comment on lines
+472
to
+474
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a better pattern to initialize the error message on the JSON object? |
||
| job["error"] = fmt("While handling '%1%': %2%\n", jobName2, (std::string) (*job2)["error"]); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't this always overwrite the assignment on line 473? |
||
| } else { | ||
| auto drvPath2 = store->parseStorePath((std::string) (*job2)["drvPath"]); | ||
| auto drv2 = store->readDerivation(drvPath2); | ||
| job["constituents"].push_back(store->printStorePath(drvPath2)); | ||
| drv.inputDrvs[drvPath2] = {drv2.outputs.begin()->first}; | ||
| } | ||
| } | ||
|
|
||
| std::string drvName(drvPath.name()); | ||
| assert(hasSuffix(drvName, drvExtension)); | ||
| drvName.resize(drvName.size() - drvExtension.size()); | ||
| auto h = std::get<Hash>(hashDerivationModulo(*store, drv, true)); | ||
| auto outPath = store->makeOutputPath("out", h, drvName); | ||
| drv.env["out"] = store->printStorePath(outPath); | ||
| drv.outputs.insert_or_assign("out", DerivationOutput { .output = DerivationOutputInputAddressed { .path = outPath } }); | ||
| auto newDrvPath = store->printStorePath(writeDerivation(*store, drv)); | ||
| std::string drvName(drvPath.name()); | ||
| assert(hasSuffix(drvName, drvExtension)); | ||
| drvName.resize(drvName.size() - drvExtension.size()); | ||
| auto h = std::get<Hash>(hashDerivationModulo(*store, drv, true)); | ||
| auto outPath = store->makeOutputPath("out", h, drvName); | ||
| drv.env["out"] = store->printStorePath(outPath); | ||
| drv.outputs.insert_or_assign("out", DerivationOutput { .output = DerivationOutputInputAddressed { .path = outPath } }); | ||
| auto newDrvPath = store->printStorePath(writeDerivation(*store, drv)); | ||
|
|
||
| debug("rewrote aggregate derivation %s -> %s", store->printStorePath(drvPath), newDrvPath); | ||
| debug("rewrote aggregate derivation %s -> %s", store->printStorePath(drvPath), newDrvPath); | ||
|
|
||
| job["drvPath"] = newDrvPath; | ||
| job["outputs"]["out"] = store->printStorePath(outPath); | ||
| } | ||
| } catch (std::exception & e) { | ||
| // Print more information to help debugging. | ||
| printError("Unexpected error in hydra-eval-jobs when handling job '%s', when producing aggregate job '%s':", lastTriedJobName, jobName); | ||
|
|
||
| job["drvPath"] = newDrvPath; | ||
| job["outputs"]["out"] = store->printStorePath(outPath); | ||
| // And throw the original exception! | ||
| throw; | ||
| } | ||
|
|
||
| job.erase("namedConstituents"); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the initialization here is not great...
I think when I wrote that up originally I was thinking about using
autoto intrinsically get the type. In that caseauto lastTriedJobName = jobNameis probably better.Otherwise, initializing with
"".What would be the better option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC the nlohman value
key()function returns reference.autoshould then deduct the typeT&which is probably not what we want here. The assignments in line 454 and 466 would then override the value in the JSON document. That being said my type deduction knowledge might be a bit rusty... I would stick with the string there.