forked from lix-project/lix
Improve error message for self reference with text hashing
The `ContentAddressWithReferences` method is made total, with error handling now squarely the caller's job. This is better.
This commit is contained in:
parent
e514b3939a
commit
6a3a87a714
3 changed files with 34 additions and 21 deletions
|
@ -2456,13 +2456,21 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs()
|
|||
},
|
||||
}, outputHash.method.raw);
|
||||
auto got = caSink.finish().first;
|
||||
|
||||
auto optCA = ContentAddressWithReferences::fromPartsOpt(
|
||||
outputHash.method,
|
||||
std::move(got),
|
||||
rewriteRefs());
|
||||
if (!optCA) {
|
||||
// TODO track distinct failure modes separately (at the time of
|
||||
// writing there is just one but `nullopt` is unclear) so this
|
||||
// message can't get out of sync.
|
||||
throw BuildError("output path '%s' has illegal content address, probably a spurious self-reference with text hashing");
|
||||
}
|
||||
ValidPathInfo newInfo0 {
|
||||
worker.store,
|
||||
outputPathName(drv->name, outputName),
|
||||
ContentAddressWithReferences::fromParts(
|
||||
outputHash.method,
|
||||
std::move(got),
|
||||
rewriteRefs()),
|
||||
*std::move(optCA),
|
||||
Hash::dummy,
|
||||
};
|
||||
if (*scratchPath != newInfo0.path) {
|
||||
|
|
|
@ -232,25 +232,29 @@ ContentAddressWithReferences ContentAddressWithReferences::withoutRefs(const Con
|
|||
}, ca.raw);
|
||||
}
|
||||
|
||||
ContentAddressWithReferences ContentAddressWithReferences::fromParts(
|
||||
ContentAddressMethod method, Hash hash, StoreReferences refs)
|
||||
std::optional<ContentAddressWithReferences> ContentAddressWithReferences::fromPartsOpt(
|
||||
ContentAddressMethod method, Hash hash, StoreReferences refs) noexcept
|
||||
{
|
||||
return std::visit(overloaded {
|
||||
[&](TextIngestionMethod _) -> ContentAddressWithReferences {
|
||||
[&](TextIngestionMethod _) -> std::optional<ContentAddressWithReferences> {
|
||||
if (refs.self)
|
||||
throw UsageError("Cannot have a self reference with text hashing scheme");
|
||||
return TextInfo {
|
||||
.hash = { .hash = std::move(hash) },
|
||||
.references = std::move(refs.others),
|
||||
return std::nullopt;
|
||||
return ContentAddressWithReferences {
|
||||
TextInfo {
|
||||
.hash = { .hash = std::move(hash) },
|
||||
.references = std::move(refs.others),
|
||||
}
|
||||
};
|
||||
},
|
||||
[&](FileIngestionMethod m2) -> ContentAddressWithReferences {
|
||||
return FixedOutputInfo {
|
||||
.hash = {
|
||||
.method = m2,
|
||||
.hash = std::move(hash),
|
||||
},
|
||||
.references = std::move(refs),
|
||||
[&](FileIngestionMethod m2) -> std::optional<ContentAddressWithReferences> {
|
||||
return ContentAddressWithReferences {
|
||||
FixedOutputInfo {
|
||||
.hash = {
|
||||
.method = m2,
|
||||
.hash = std::move(hash),
|
||||
},
|
||||
.references = std::move(refs),
|
||||
}
|
||||
};
|
||||
},
|
||||
}, method.raw);
|
||||
|
|
|
@ -303,10 +303,11 @@ struct ContentAddressWithReferences
|
|||
*
|
||||
* @param refs References to other store objects or oneself.
|
||||
*
|
||||
* Do note that not all combinations are supported.
|
||||
* Do note that not all combinations are supported; `nullopt` is
|
||||
* returns for invalid combinations.
|
||||
*/
|
||||
static ContentAddressWithReferences fromParts(
|
||||
ContentAddressMethod method, Hash hash, StoreReferences refs);
|
||||
static std::optional<ContentAddressWithReferences> fromPartsOpt(
|
||||
ContentAddressMethod method, Hash hash, StoreReferences refs) noexcept;
|
||||
|
||||
ContentAddressMethod getMethod() const;
|
||||
|
||||
|
|
Loading…
Reference in a new issue