Commit 05620fa8 authored by Kenton Varda's avatar Kenton Varda

Throw new 'unimplemented' exception type from unimplemented capability methods.

parent 0af31360
...@@ -62,6 +62,7 @@ TEST(Capability, Basic) { ...@@ -62,6 +62,7 @@ TEST(Capability, Basic) {
[](Response<test::TestInterface::BarResults>&& response) { [](Response<test::TestInterface::BarResults>&& response) {
ADD_FAILURE() << "Expected bar() call to fail."; ADD_FAILURE() << "Expected bar() call to fail.";
}, [&](kj::Exception&& e) { }, [&](kj::Exception&& e) {
EXPECT_EQ(kj::Exception::Type::UNIMPLEMENTED, e.getType());
barFailed = true; barFailed = true;
}); });
...@@ -243,6 +244,7 @@ TEST(Capability, DynamicClient) { ...@@ -243,6 +244,7 @@ TEST(Capability, DynamicClient) {
[](Response<DynamicStruct>&& response) { [](Response<DynamicStruct>&& response) {
ADD_FAILURE() << "Expected bar() call to fail."; ADD_FAILURE() << "Expected bar() call to fail.";
}, [&](kj::Exception&& e) { }, [&](kj::Exception&& e) {
EXPECT_EQ(kj::Exception::Type::UNIMPLEMENTED, e.getType());
barFailed = true; barFailed = true;
}); });
...@@ -364,7 +366,7 @@ public: ...@@ -364,7 +366,7 @@ public:
EXPECT_ANY_THROW(context.getParams()); EXPECT_ANY_THROW(context.getParams());
return kj::READY_NOW; return kj::READY_NOW;
} else { } else {
KJ_FAIL_ASSERT("Method not implemented", methodName) { break; } KJ_UNIMPLEMENTED("Method not implemented", methodName) { break; }
return kj::READY_NOW; return kj::READY_NOW;
} }
} }
...@@ -394,6 +396,7 @@ TEST(Capability, DynamicServer) { ...@@ -394,6 +396,7 @@ TEST(Capability, DynamicServer) {
[](Response<test::TestInterface::BarResults>&& response) { [](Response<test::TestInterface::BarResults>&& response) {
ADD_FAILURE() << "Expected bar() call to fail."; ADD_FAILURE() << "Expected bar() call to fail.";
}, [&](kj::Exception&& e) { }, [&](kj::Exception&& e) {
EXPECT_EQ(kj::Exception::Type::UNIMPLEMENTED, e.getType());
barFailed = true; barFailed = true;
}); });
......
...@@ -74,7 +74,7 @@ Capability::Client::Client(kj::Exception&& exception) ...@@ -74,7 +74,7 @@ Capability::Client::Client(kj::Exception&& exception)
kj::Promise<void> Capability::Server::internalUnimplemented( kj::Promise<void> Capability::Server::internalUnimplemented(
const char* actualInterfaceName, uint64_t requestedTypeId) { const char* actualInterfaceName, uint64_t requestedTypeId) {
KJ_FAIL_REQUIRE("Requested interface not implemented.", actualInterfaceName, requestedTypeId) { KJ_UNIMPLEMENTED("Requested interface not implemented.", actualInterfaceName, requestedTypeId) {
// Recoverable exception will be caught by promise framework. // Recoverable exception will be caught by promise framework.
// We can't "return kj::READY_NOW;" inside this block because it causes a memory leak due to // We can't "return kj::READY_NOW;" inside this block because it causes a memory leak due to
...@@ -88,7 +88,7 @@ kj::Promise<void> Capability::Server::internalUnimplemented( ...@@ -88,7 +88,7 @@ kj::Promise<void> Capability::Server::internalUnimplemented(
kj::Promise<void> Capability::Server::internalUnimplemented( kj::Promise<void> Capability::Server::internalUnimplemented(
const char* interfaceName, uint64_t typeId, uint16_t methodId) { const char* interfaceName, uint64_t typeId, uint16_t methodId) {
KJ_FAIL_REQUIRE("Method not implemented.", interfaceName, typeId, methodId) { KJ_UNIMPLEMENTED("Method not implemented.", interfaceName, typeId, methodId) {
// Recoverable exception will be caught by promise framework. // Recoverable exception will be caught by promise framework.
break; break;
} }
...@@ -97,7 +97,7 @@ kj::Promise<void> Capability::Server::internalUnimplemented( ...@@ -97,7 +97,7 @@ kj::Promise<void> Capability::Server::internalUnimplemented(
kj::Promise<void> Capability::Server::internalUnimplemented( kj::Promise<void> Capability::Server::internalUnimplemented(
const char* interfaceName, const char* methodName, uint64_t typeId, uint16_t methodId) { const char* interfaceName, const char* methodName, uint64_t typeId, uint16_t methodId) {
KJ_FAIL_REQUIRE("Method not implemented.", interfaceName, typeId, methodName, methodId) { KJ_UNIMPLEMENTED("Method not implemented.", interfaceName, typeId, methodName, methodId) {
// Recoverable exception will be caught by promise framework. // Recoverable exception will be caught by promise framework.
break; break;
} }
......
...@@ -251,12 +251,18 @@ void Debug::Fault::fatal() { ...@@ -251,12 +251,18 @@ void Debug::Fault::fatal() {
abort(); abort();
} }
void Debug::Fault::init(
const char* file, int line, Exception::Type type,
const char* condition, const char* macroArgs, ArrayPtr<String> argValues) {
exception = new Exception(type, file, line,
makeDescriptionImpl(ASSERTION, condition, 0, macroArgs, argValues));
}
void Debug::Fault::init( void Debug::Fault::init(
const char* file, int line, int osErrorNumber, const char* file, int line, int osErrorNumber,
const char* condition, const char* macroArgs, ArrayPtr<String> argValues) { const char* condition, const char* macroArgs, ArrayPtr<String> argValues) {
exception = new Exception(typeOfErrno(osErrorNumber), file, line, exception = new Exception(typeOfErrno(osErrorNumber), file, line,
makeDescriptionImpl(osErrorNumber != 0 ? SYSCALL : ASSERTION, condition, makeDescriptionImpl(SYSCALL, condition, osErrorNumber, macroArgs, argValues));
osErrorNumber, macroArgs, argValues));
} }
String Debug::makeDescriptionInternal(const char* macroArgs, ArrayPtr<String> argValues) { String Debug::makeDescriptionInternal(const char* macroArgs, ArrayPtr<String> argValues) {
......
...@@ -144,11 +144,11 @@ namespace kj { ...@@ -144,11 +144,11 @@ namespace kj {
#define KJ_REQUIRE(cond, ...) \ #define KJ_REQUIRE(cond, ...) \
if (KJ_LIKELY(cond)) {} else \ if (KJ_LIKELY(cond)) {} else \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, 0, \ for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \
#cond, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) #cond, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal())
#define KJ_FAIL_REQUIRE(...) \ #define KJ_FAIL_REQUIRE(...) \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, 0, \ for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \
nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal())
#define KJ_SYSCALL(call, ...) \ #define KJ_SYSCALL(call, ...) \
...@@ -165,6 +165,10 @@ namespace kj { ...@@ -165,6 +165,10 @@ namespace kj {
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \
errorNumber, code, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal()) errorNumber, code, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal())
#define KJ_UNIMPLEMENTED(...) \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \
nullptr, "" #__VA_ARGS__, __VA_ARGS__);; f.fatal())
#define KJ_CONTEXT(...) \ #define KJ_CONTEXT(...) \
auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \ auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \
return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \ return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \
...@@ -198,11 +202,11 @@ namespace kj { ...@@ -198,11 +202,11 @@ namespace kj {
#define KJ_REQUIRE(cond, ...) \ #define KJ_REQUIRE(cond, ...) \
if (KJ_LIKELY(cond)) {} else \ if (KJ_LIKELY(cond)) {} else \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, 0, \ for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \
#cond, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) #cond, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal())
#define KJ_FAIL_REQUIRE(...) \ #define KJ_FAIL_REQUIRE(...) \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, 0, \ for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::FAILED, \
nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal())
#define KJ_SYSCALL(call, ...) \ #define KJ_SYSCALL(call, ...) \
...@@ -219,6 +223,10 @@ namespace kj { ...@@ -219,6 +223,10 @@ namespace kj {
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \ for (::kj::_::Debug::Fault f(__FILE__, __LINE__, \
errorNumber, code, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal()) errorNumber, code, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal())
#define KJ_UNIMPLEMENTED(...) \
for (::kj::_::Debug::Fault f(__FILE__, __LINE__, ::kj::Exception::Type::UNIMPLEMENTED, \
nullptr, #__VA_ARGS__, ##__VA_ARGS__);; f.fatal())
#define KJ_CONTEXT(...) \ #define KJ_CONTEXT(...) \
auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \ auto KJ_UNIQUE_NAME(_kjContextFunc) = [&]() -> ::kj::_::Debug::Context::Value { \
return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \ return ::kj::_::Debug::Context::Value(__FILE__, __LINE__, \
...@@ -292,8 +300,13 @@ public: ...@@ -292,8 +300,13 @@ public:
class Fault { class Fault {
public: public:
template <typename... Params> template <typename... Params>
Fault(const char* file, int line, Exception::Type type,
const char* condition, const char* macroArgs, Params&&... params);
template <typename... Params>
Fault(const char* file, int line, int osErrorNumber, Fault(const char* file, int line, int osErrorNumber,
const char* condition, const char* macroArgs, Params&&... params); const char* condition, const char* macroArgs, Params&&... params);
Fault(const char* file, int line, Exception::Type type,
const char* condition, const char* macroArgs);
Fault(const char* file, int line, int osErrorNumber, Fault(const char* file, int line, int osErrorNumber,
const char* condition, const char* macroArgs); const char* condition, const char* macroArgs);
~Fault() noexcept(false); ~Fault() noexcept(false);
...@@ -302,6 +315,8 @@ public: ...@@ -302,6 +315,8 @@ public:
// Throw the exception. // Throw the exception.
private: private:
void init(const char* file, int line, Exception::Type type,
const char* condition, const char* macroArgs, ArrayPtr<String> argValues);
void init(const char* file, int line, int osErrorNumber, void init(const char* file, int line, int osErrorNumber,
const char* condition, const char* macroArgs, ArrayPtr<String> argValues); const char* condition, const char* macroArgs, ArrayPtr<String> argValues);
...@@ -390,6 +405,15 @@ inline void Debug::log<>(const char* file, int line, Severity severity, const ch ...@@ -390,6 +405,15 @@ inline void Debug::log<>(const char* file, int line, Severity severity, const ch
logInternal(file, line, severity, macroArgs, nullptr); logInternal(file, line, severity, macroArgs, nullptr);
} }
template <typename... Params>
Debug::Fault::Fault(const char* file, int line, Exception::Type type,
const char* condition, const char* macroArgs, Params&&... params)
: exception(nullptr) {
String argValues[sizeof...(Params)] = {str(params)...};
init(file, line, type, condition, macroArgs,
arrayPtr(argValues, sizeof...(Params)));
}
template <typename... Params> template <typename... Params>
Debug::Fault::Fault(const char* file, int line, int osErrorNumber, Debug::Fault::Fault(const char* file, int line, int osErrorNumber,
const char* condition, const char* macroArgs, Params&&... params) const char* condition, const char* macroArgs, Params&&... params)
...@@ -405,6 +429,12 @@ inline Debug::Fault::Fault(const char* file, int line, int osErrorNumber, ...@@ -405,6 +429,12 @@ inline Debug::Fault::Fault(const char* file, int line, int osErrorNumber,
init(file, line, osErrorNumber, condition, macroArgs, nullptr); init(file, line, osErrorNumber, condition, macroArgs, nullptr);
} }
inline Debug::Fault::Fault(const char* file, int line, kj::Exception::Type type,
const char* condition, const char* macroArgs)
: exception(nullptr) {
init(file, line, type, condition, macroArgs, nullptr);
}
template <typename Call> template <typename Call>
Debug::SyscallResult Debug::syscall(Call&& call, bool nonblocking) { Debug::SyscallResult Debug::syscall(Call&& call, bool nonblocking) {
while (call() < 0) { while (call() < 0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment