Serialize exceptions from the daemon to the client
This commit is contained in:
parent
be149acfda
commit
c43e882f54
3 changed files with 24 additions and 11 deletions
|
@ -101,17 +101,20 @@ struct TunnelLogger : public Logger
|
||||||
|
|
||||||
/* stopWork() means that we're done; stop sending stderr to the
|
/* stopWork() means that we're done; stop sending stderr to the
|
||||||
client. */
|
client. */
|
||||||
void stopWork(bool success = true, const string & msg = "", unsigned int status = 0)
|
void stopWork(const Error * ex = nullptr)
|
||||||
{
|
{
|
||||||
auto state(state_.lock());
|
auto state(state_.lock());
|
||||||
|
|
||||||
state->canSendStderr = false;
|
state->canSendStderr = false;
|
||||||
|
|
||||||
if (success)
|
if (!ex)
|
||||||
to << STDERR_LAST;
|
to << STDERR_LAST;
|
||||||
else {
|
else {
|
||||||
to << STDERR_ERROR << msg;
|
if (GET_PROTOCOL_MINOR(clientVersion) >= 26) {
|
||||||
if (status != 0) to << status;
|
to << STDERR_ERROR << *ex;
|
||||||
|
} else {
|
||||||
|
to << STDERR_ERROR << ex->what() << ex->status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -935,10 +938,11 @@ void processConnection(
|
||||||
during addTextToStore() / importPath(). If that
|
during addTextToStore() / importPath(). If that
|
||||||
happens, just send the error message and exit. */
|
happens, just send the error message and exit. */
|
||||||
bool errorAllowed = tunnelLogger->state_.lock()->canSendStderr;
|
bool errorAllowed = tunnelLogger->state_.lock()->canSendStderr;
|
||||||
tunnelLogger->stopWork(false, e.msg(), e.status);
|
tunnelLogger->stopWork(&e);
|
||||||
if (!errorAllowed) throw;
|
if (!errorAllowed) throw;
|
||||||
} catch (std::bad_alloc & e) {
|
} catch (std::bad_alloc & e) {
|
||||||
tunnelLogger->stopWork(false, "Nix daemon out of memory", 1);
|
auto ex = Error("Nix daemon out of memory");
|
||||||
|
tunnelLogger->stopWork(&ex);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,8 +951,13 @@ void processConnection(
|
||||||
assert(!tunnelLogger->state_.lock()->canSendStderr);
|
assert(!tunnelLogger->state_.lock()->canSendStderr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} catch (Error & e) {
|
||||||
|
tunnelLogger->stopWork(&e);
|
||||||
|
to.flush();
|
||||||
|
return;
|
||||||
} catch (std::exception & e) {
|
} catch (std::exception & e) {
|
||||||
tunnelLogger->stopWork(false, e.what(), 1);
|
auto ex = Error(e.what());
|
||||||
|
tunnelLogger->stopWork(&ex);
|
||||||
to.flush();
|
to.flush();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -925,9 +925,13 @@ std::exception_ptr RemoteStore::Connection::processStderr(Sink * sink, Source *
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (msg == STDERR_ERROR) {
|
else if (msg == STDERR_ERROR) {
|
||||||
string error = readString(from);
|
if (GET_PROTOCOL_MINOR(daemonVersion) >= 26) {
|
||||||
unsigned int status = readInt(from);
|
return std::make_exception_ptr(readError(from));
|
||||||
return std::make_exception_ptr(Error(status, error));
|
} else {
|
||||||
|
string error = readString(from);
|
||||||
|
unsigned int status = readInt(from);
|
||||||
|
return std::make_exception_ptr(Error(status, error));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (msg == STDERR_NEXT)
|
else if (msg == STDERR_NEXT)
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace nix {
|
||||||
#define WORKER_MAGIC_1 0x6e697863
|
#define WORKER_MAGIC_1 0x6e697863
|
||||||
#define WORKER_MAGIC_2 0x6478696f
|
#define WORKER_MAGIC_2 0x6478696f
|
||||||
|
|
||||||
#define PROTOCOL_VERSION 0x119
|
#define PROTOCOL_VERSION 0x11a
|
||||||
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
|
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
|
||||||
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue