Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
0af31360
Commit
0af31360
authored
Nov 29, 2014
by
Kenton Varda
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'exception-rewrite'
Conflicts: c++/src/kj/common.h
parents
79a81a09
4ee25e43
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
360 additions
and
295 deletions
+360
-295
capability.c++
c++/src/capnp/capability.c++
+1
-2
capnp.c++
c++/src/capnp/compiler/capnp.c++
+4
-11
rpc-test.c++
c++/src/capnp/rpc-test.c++
+1
-3
rpc.c++
c++/src/capnp/rpc.c++
+7
-42
rpc.capnp
c++/src/capnp/rpc.capnp
+75
-18
rpc.capnp.c++
c++/src/capnp/rpc.capnp.c++
+67
-48
rpc.capnp.h
c++/src/capnp/rpc.capnp.h
+41
-21
schema-parser.c++
c++/src/capnp/schema-parser.c++
+2
-2
async-inl.h
c++/src/kj/async-inl.h
+1
-3
common.c++
c++/src/kj/common.c++
+2
-13
common.h
c++/src/kj/common.h
+3
-18
debug-test.c++
c++/src/kj/debug-test.c++
+43
-19
debug.c++
c++/src/kj/debug.c++
+48
-9
debug.h
c++/src/kj/debug.h
+0
-0
exception.c++
c++/src/kj/exception.c++
+29
-42
exception.h
c++/src/kj/exception.h
+31
-39
time.c++
c++/src/kj/time.c++
+1
-3
time.h
c++/src/kj/time.h
+4
-2
No files found.
c++/src/capnp/capability.c++
View file @
0af31360
...
...
@@ -575,8 +575,7 @@ class BrokenClient final: public ClientHook, public kj::Refcounted {
public
:
BrokenClient
(
const
kj
::
Exception
&
exception
)
:
exception
(
exception
)
{}
BrokenClient
(
const
kj
::
StringPtr
description
)
:
exception
(
kj
::
Exception
::
Nature
::
PRECONDITION
,
kj
::
Exception
::
Durability
::
PERMANENT
,
""
,
0
,
kj
::
str
(
description
))
{}
:
exception
(
kj
::
Exception
::
Type
::
FAILED
,
""
,
0
,
kj
::
str
(
description
))
{}
Request
<
AnyPointer
,
AnyPointer
>
newCall
(
uint64_t
interfaceId
,
uint16_t
methodId
,
kj
::
Maybe
<
MessageSize
>
sizeHint
)
override
{
...
...
c++/src/capnp/compiler/capnp.c++
View file @
0af31360
...
...
@@ -646,17 +646,10 @@ public:
private
:
struct
ParseErrorCatcher
:
public
kj
::
ExceptionCallback
{
void
onRecoverableException
(
kj
::
Exception
&&
e
)
{
if
(
e
.
getNature
()
==
kj
::
Exception
::
Nature
::
PRECONDITION
)
{
// This is probably a problem with the input. Let's try to report it more nicely.
// Only capture the first exception, on the assumption that later exceptions are probably
// just cascading problems.
if
(
exception
==
nullptr
)
{
exception
=
kj
::
mv
(
e
);
}
}
else
{
// This is probably a bug, not a problem with the input.
ExceptionCallback
::
onRecoverableException
(
kj
::
mv
(
e
));
// Only capture the first exception, on the assumption that later exceptions are probably
// just cascading problems.
if
(
exception
==
nullptr
)
{
exception
=
kj
::
mv
(
e
);
}
}
...
...
c++/src/capnp/rpc-test.c++
View file @
0af31360
...
...
@@ -190,9 +190,7 @@ public:
TestNetworkAdapter
(
TestNetwork
&
network
)
:
network
(
network
)
{}
~
TestNetworkAdapter
()
{
kj
::
Exception
exception
(
kj
::
Exception
::
Nature
::
PRECONDITION
,
kj
::
Exception
::
Durability
::
PERMANENT
,
__FILE__
,
__LINE__
,
kj
::
str
(
"Network was destroyed."
));
kj
::
Exception
exception
=
KJ_EXCEPTION
(
FAILED
,
"Network was destroyed."
);
for
(
auto
&
entry
:
connections
)
{
entry
.
second
->
disconnect
(
kj
::
cp
(
exception
));
}
...
...
c++/src/capnp/rpc.c++
View file @
0af31360
...
...
@@ -107,45 +107,15 @@ Orphan<List<rpc::PromisedAnswer::Op>> fromPipelineOps(
}
kj
::
Exception
toException
(
const
rpc
::
Exception
::
Reader
&
exception
)
{
kj
::
Exception
::
Nature
nature
=
exception
.
getIsCallersFault
()
?
kj
::
Exception
::
Nature
::
PRECONDITION
:
kj
::
Exception
::
Nature
::
LOCAL_BUG
;
kj
::
Exception
::
Durability
durability
;
switch
(
exception
.
getDurability
())
{
default
:
case
rpc
:
:
Exception
::
Durability
::
PERMANENT
:
durability
=
kj
::
Exception
::
Durability
::
PERMANENT
;
break
;
case
rpc
:
:
Exception
::
Durability
::
TEMPORARY
:
durability
=
kj
::
Exception
::
Durability
::
TEMPORARY
;
break
;
case
rpc
:
:
Exception
::
Durability
::
OVERLOADED
:
durability
=
kj
::
Exception
::
Durability
::
OVERLOADED
;
break
;
}
return
kj
::
Exception
(
nature
,
durability
,
"(remote)"
,
0
,
kj
::
str
(
"remote exception: "
,
exception
.
getReason
()));
return
kj
::
Exception
(
static_cast
<
kj
::
Exception
::
Type
>
(
exception
.
getType
()),
"(remote)"
,
0
,
kj
::
str
(
"remote exception: "
,
exception
.
getReason
()));
}
void
fromException
(
const
kj
::
Exception
&
exception
,
rpc
::
Exception
::
Builder
builder
)
{
// TODO(someday): Indicate the remote server name as part of the stack trace. Maybe even
// transmit stack traces?
builder
.
setReason
(
exception
.
getDescription
());
builder
.
setIsCallersFault
(
exception
.
getNature
()
==
kj
::
Exception
::
Nature
::
PRECONDITION
);
switch
(
exception
.
getDurability
())
{
case
kj
:
:
Exception
::
Durability
::
PERMANENT
:
builder
.
setDurability
(
rpc
::
Exception
::
Durability
::
PERMANENT
);
break
;
case
kj
:
:
Exception
::
Durability
::
TEMPORARY
:
builder
.
setDurability
(
rpc
::
Exception
::
Durability
::
TEMPORARY
);
break
;
case
kj
:
:
Exception
::
Durability
::
OVERLOADED
:
builder
.
setDurability
(
rpc
::
Exception
::
Durability
::
OVERLOADED
);
break
;
}
builder
.
setType
(
static_cast
<
rpc
::
Exception
::
Type
>
(
exception
.
getType
()));
}
uint
exceptionSizeHint
(
const
kj
::
Exception
&
exception
)
{
...
...
@@ -318,9 +288,8 @@ public:
return
;
}
kj
::
Exception
networkException
(
kj
::
Exception
::
Nature
::
NETWORK_FAILURE
,
kj
::
Exception
::
Durability
::
PERMANENT
,
__FILE__
,
__LINE__
,
kj
::
str
(
"Disconnected: "
,
exception
.
getDescription
()));
kj
::
Exception
networkException
(
kj
::
Exception
::
Type
::
DISCONNECTED
,
exception
.
getFile
(),
exception
.
getLine
(),
kj
::
heapString
(
exception
.
getDescription
()));
KJ_IF_MAYBE
(
newException
,
kj
::
runCatchingExceptions
([
&
]()
{
// Carefully pull all the objects out of the tables prior to releasing them because their
...
...
@@ -1970,9 +1939,7 @@ private:
handleMessage
(
kj
::
mv
(
*
m
));
return
true
;
}
else
{
disconnect
(
kj
::
Exception
(
kj
::
Exception
::
Nature
::
PRECONDITION
,
kj
::
Exception
::
Durability
::
PERMANENT
,
__FILE__
,
__LINE__
,
kj
::
str
(
"Peer disconnected."
)));
disconnect
(
KJ_EXCEPTION
(
DISCONNECTED
,
"Peer disconnected."
));
return
false
;
}
}).
then
([
this
](
bool
keepGoing
)
{
...
...
@@ -2626,9 +2593,7 @@ public:
// disassemble it.
if
(
!
connections
.
empty
())
{
kj
::
Vector
<
kj
::
Own
<
RpcConnectionState
>>
deleteMe
(
connections
.
size
());
kj
::
Exception
shutdownException
(
kj
::
Exception
::
Nature
::
LOCAL_BUG
,
kj
::
Exception
::
Durability
::
PERMANENT
,
__FILE__
,
__LINE__
,
kj
::
str
(
"RpcSystem was destroyed."
));
kj
::
Exception
shutdownException
=
KJ_EXCEPTION
(
FAILED
,
"RpcSystem was destroyed."
);
for
(
auto
&
entry
:
connections
)
{
entry
.
second
->
disconnect
(
kj
::
cp
(
shutdownException
));
deleteMe
.
add
(
kj
::
mv
(
entry
.
second
));
...
...
c++/src/capnp/rpc.capnp
View file @
0af31360
...
...
@@ -1053,29 +1053,86 @@ struct Exception {
# **(level 0)**
#
# Describes an arbitrary error that prevented an operation (e.g. a call) from completing.
#
# Cap'n Proto exceptions always indicate that something went wrong. In other words, in a fantasy
# world where everything always works as expected, no exceptions would ever be thrown. Clients
# should only ever catch exceptions as a means to implement fault-tolerance, where "fault" can
# mean:
# - Bugs.
# - Invalid input.
# - Configuration errors.
# - Network probles.
# - Insufficient resources.
# - Version skew (unimplemented functionality).
# - Other logistical problems.
#
# Exceptions should NOT be used to flag application-specific conditions that a client is expected
# to handle in an application-specific way. Put another way, in the Cap'n Proto world,
# "checked exceptions" (where an interface explicitly defines the exceptions it throws and
# clients are forced by the type system to handle those exceptions) do NOT make sense.
reason @0 :Text;
# Human-readable failure description.
isCallersFault @1 :Bool;
# In the best estimate of the error source, is it the caller's fault that this error occurred
# (like HTTP 400), or is it the callee's fault (like HTTP 500)? Or, put another way, if an
# automated bug report were to be generated for this error, should it be initially filed on the
# caller's code or the callee's? This is a guess. Generally guesses should err towards blaming
# the callee -- at the very least, the callee should be on the hook for improving their error
# handling to be more confident in assigning blame.
durability @2 :Durability;
# In the best estimate of the error source, is this error likely to repeat if the same call is
# executed again? Callers might use this to decide when to retry a request.
enum Durability {
permanent @0; # Retrying the exact same operation will fail in the same way.
temporary @1; # Retrying the exact same operation might succeed.
overloaded @2; # The error may be due to the system being overloaded. Retrying may work
# later on, but for now the caller should not retry right away as this will
# likely exacerbate the problem.
type @3 :Type;
# The type of the error. The purpose of this enum is not to describe the error itself, but
# rather to describe how the client might want to respond to the error.
enum Type {
failed @0;
# A generic problem occurred, and it is believed that if the operation were repeated without
# any change in the state of the world, the problem would occur again.
#
# A client might respond to this error by logging it for investigation by the developer and/or
# displaying it to the user.
overloaded @1;
# The request was rejected due to a temporary lack of resources.
#
# Examples include:
# - There's not enough CPU time to keep up with incoming requests, so some are rejected.
# - The server ran out of RAM or disk space during the request.
# - The operation timed out (took significantly longer than it should have).
#
# A client might respond to this error by scheduling to retry the operation much later. The
# client should NOT retry again immediately since this would likely exacerbate the problem.
disconnected @2;
# The method failed because a connection to some necessary capability was lost.
#
# Examples include:
# - The client introduced the server to a third-party capability, the connection to that third
# party was subsequently lost, and then the client requested that the server use the dead
# capability for something.
# - The client previously requested that the server obtain a capability from some third party.
# The server returned a capability to an object wrapping the third-party capability. Later,
# the server's connection to the third party was lost.
# - The capability has been revoked. Revocation does not necessarily mean that the client is
# no longer authorized to use the capability; it is often used simply as a way to force the
# client to repeat the setup process, perhaps to efficiently move them to a new back-end or
# get them to recognize some other change that has occurred.
#
# A client should normally respond to this error by releasing all capabilities it is currently
# holding related to the one it called and then re-creating them by restoring SturdyRefs and/or
# repeating the method calls used to create them originally. In other words, disconnect and
# start over. This should in turn cause the server to obtain a new copy of the capability that
# it lost, thus making everything work.
#
# If the client receives another `disconnencted` error in the process of rebuilding the
# capability and retrying the call, it should treat this as an `overloaded` error: the network
# is currently unreliable, possibly due to load or other temporary issues.
unimplemented @3;
# The server doesn't implement the requested method. If there is some other method that the
# client could call (perhaps an older and/or slower interface), it should try that instead.
# Otherwise, this should be treated like `serverError`.
}
obsoleteIsCallersFault @1 :Bool;
# OBSOLETE. Ignore.
obsoleteDurability @2 :UInt16;
# OBSOLETE. See `type` instead.
}
# ========================================================================================
...
...
c++/src/capnp/rpc.capnp.c++
View file @
0af31360
...
...
@@ -1734,7 +1734,7 @@ const ::capnp::_::RawSchema s_d37007fde1f0027d = {
0
,
2
,
i_d37007fde1f0027d
,
nullptr
,
nullptr
,
{
&
s_d37007fde1f0027d
,
nullptr
,
nullptr
,
0
,
0
,
nullptr
}
};
#endif // !CAPNP_LITE
static
const
::
capnp
::
_
::
AlignedData
<
69
>
b_d625b7063acf691a
=
{
static
const
::
capnp
::
_
::
AlignedData
<
85
>
b_d625b7063acf691a
=
{
{
0
,
0
,
0
,
0
,
5
,
0
,
6
,
0
,
26
,
105
,
207
,
58
,
6
,
183
,
37
,
214
,
16
,
0
,
0
,
0
,
1
,
0
,
1
,
0
,
...
...
@@ -1744,7 +1744,7 @@ static const ::capnp::_::AlignedData<69> b_d625b7063acf691a = {
21
,
0
,
0
,
0
,
210
,
0
,
0
,
0
,
33
,
0
,
0
,
0
,
23
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
4
5
,
0
,
0
,
0
,
175
,
0
,
0
,
0
,
4
1
,
0
,
0
,
0
,
231
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
99
,
97
,
112
,
110
,
112
,
47
,
114
,
112
,
...
...
@@ -1752,32 +1752,38 @@ static const ::capnp::_::AlignedData<69> b_d625b7063acf691a = {
69
,
120
,
99
,
101
,
112
,
116
,
105
,
111
,
110
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
4
,
0
,
0
,
0
,
1
,
0
,
1
,
0
,
88
,
249
,
182
,
7
,
38
,
218
,
174
,
187
,
1
,
0
,
0
,
0
,
90
,
0
,
0
,
0
,
68
,
117
,
114
,
97
,
98
,
105
,
108
,
105
,
116
,
121
,
0
,
0
,
0
,
0
,
0
,
0
,
12
,
0
,
0
,
0
,
3
,
0
,
4
,
0
,
88
,
189
,
76
,
63
,
226
,
150
,
140
,
178
,
1
,
0
,
0
,
0
,
42
,
0
,
0
,
0
,
84
,
121
,
112
,
101
,
0
,
0
,
0
,
0
,
16
,
0
,
0
,
0
,
3
,
0
,
4
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
69
,
0
,
0
,
0
,
58
,
0
,
0
,
0
,
97
,
0
,
0
,
0
,
58
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
64
,
0
,
0
,
0
,
3
,
0
,
1
,
0
,
76
,
0
,
0
,
0
,
2
,
0
,
1
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
92
,
0
,
0
,
0
,
3
,
0
,
1
,
0
,
104
,
0
,
0
,
0
,
2
,
0
,
1
,
0
,
2
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
73
,
0
,
0
,
0
,
122
,
0
,
0
,
0
,
101
,
0
,
0
,
0
,
186
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
72
,
0
,
0
,
0
,
3
,
0
,
1
,
0
,
84
,
0
,
0
,
0
,
2
,
0
,
1
,
0
,
2
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
104
,
0
,
0
,
0
,
3
,
0
,
1
,
0
,
116
,
0
,
0
,
0
,
2
,
0
,
1
,
0
,
3
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
2
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
81
,
0
,
0
,
0
,
90
,
0
,
0
,
0
,
113
,
0
,
0
,
0
,
154
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
80
,
0
,
0
,
0
,
3
,
0
,
1
,
0
,
92
,
0
,
0
,
0
,
2
,
0
,
1
,
0
,
116
,
0
,
0
,
0
,
3
,
0
,
1
,
0
,
128
,
0
,
0
,
0
,
2
,
0
,
1
,
0
,
1
,
0
,
0
,
0
,
2
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
3
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
125
,
0
,
0
,
0
,
42
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
120
,
0
,
0
,
0
,
3
,
0
,
1
,
0
,
132
,
0
,
0
,
0
,
2
,
0
,
1
,
0
,
114
,
101
,
97
,
115
,
111
,
110
,
0
,
0
,
12
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
...
...
@@ -1786,7 +1792,8 @@ static const ::capnp::_::AlignedData<69> b_d625b7063acf691a = {
12
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
105
,
115
,
67
,
97
,
108
,
108
,
101
,
114
,
111
,
98
,
115
,
111
,
108
,
101
,
116
,
101
,
73
,
115
,
67
,
97
,
108
,
108
,
101
,
114
,
115
,
70
,
97
,
117
,
108
,
116
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
...
...
@@ -1795,10 +1802,19 @@ static const ::capnp::_::AlignedData<69> b_d625b7063acf691a = {
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
100
,
117
,
114
,
97
,
98
,
105
,
108
,
105
,
111
,
98
,
115
,
111
,
108
,
101
,
116
,
101
,
68
,
117
,
114
,
97
,
98
,
105
,
108
,
105
,
116
,
121
,
0
,
0
,
0
,
0
,
0
,
0
,
7
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
7
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
116
,
121
,
112
,
101
,
0
,
0
,
0
,
0
,
15
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
88
,
249
,
182
,
7
,
38
,
218
,
174
,
187
,
88
,
189
,
76
,
63
,
226
,
150
,
140
,
178
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
15
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
...
...
@@ -1808,60 +1824,63 @@ static const ::capnp::_::AlignedData<69> b_d625b7063acf691a = {
::
capnp
::
word
const
*
const
bp_d625b7063acf691a
=
b_d625b7063acf691a
.
words
;
#if !CAPNP_LITE
static
const
::
capnp
::
_
::
RawSchema
*
const
d_d625b7063acf691a
[]
=
{
&
s_b
baeda2607b6f9
58
,
&
s_b
28c96e23f4cbd
58
,
};
static
const
uint16_t
m_d625b7063acf691a
[]
=
{
2
,
1
,
0
};
static
const
uint16_t
i_d625b7063acf691a
[]
=
{
0
,
1
,
2
};
static
const
uint16_t
m_d625b7063acf691a
[]
=
{
2
,
1
,
0
,
3
};
static
const
uint16_t
i_d625b7063acf691a
[]
=
{
0
,
1
,
2
,
3
};
const
::
capnp
::
_
::
RawSchema
s_d625b7063acf691a
=
{
0xd625b7063acf691a
,
b_d625b7063acf691a
.
words
,
69
,
d_d625b7063acf691a
,
m_d625b7063acf691a
,
1
,
3
,
i_d625b7063acf691a
,
nullptr
,
nullptr
,
{
&
s_d625b7063acf691a
,
nullptr
,
nullptr
,
0
,
0
,
nullptr
}
0xd625b7063acf691a
,
b_d625b7063acf691a
.
words
,
85
,
d_d625b7063acf691a
,
m_d625b7063acf691a
,
1
,
4
,
i_d625b7063acf691a
,
nullptr
,
nullptr
,
{
&
s_d625b7063acf691a
,
nullptr
,
nullptr
,
0
,
0
,
nullptr
}
};
#endif // !CAPNP_LITE
static
const
::
capnp
::
_
::
AlignedData
<
3
4
>
b_bbaeda2607b6f9
58
=
{
static
const
::
capnp
::
_
::
AlignedData
<
3
7
>
b_b28c96e23f4cbd
58
=
{
{
0
,
0
,
0
,
0
,
5
,
0
,
6
,
0
,
88
,
249
,
182
,
7
,
38
,
218
,
174
,
187
,
88
,
189
,
76
,
63
,
226
,
150
,
140
,
178
,
26
,
0
,
0
,
0
,
2
,
0
,
0
,
0
,
26
,
105
,
207
,
58
,
6
,
183
,
37
,
214
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
21
,
0
,
0
,
0
,
42
,
1
,
0
,
0
,
3
7
,
0
,
0
,
0
,
7
,
0
,
0
,
0
,
21
,
0
,
0
,
0
,
250
,
0
,
0
,
0
,
3
3
,
0
,
0
,
0
,
7
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
33
,
0
,
0
,
0
,
79
,
0
,
0
,
0
,
29
,
0
,
0
,
0
,
103
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
99
,
97
,
112
,
110
,
112
,
47
,
114
,
112
,
99
,
46
,
99
,
97
,
112
,
110
,
112
,
58
,
69
,
120
,
99
,
101
,
112
,
116
,
105
,
111
,
110
,
46
,
68
,
117
,
114
,
97
,
98
,
105
,
108
,
105
,
116
,
121
,
0
,
0
,
0
,
0
,
110
,
46
,
84
,
121
,
112
,
101
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
1
,
0
,
1
2
,
0
,
0
,
0
,
1
,
0
,
2
,
0
,
1
6
,
0
,
0
,
0
,
1
,
0
,
2
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
29
,
0
,
0
,
0
,
82
,
0
,
0
,
0
,
41
,
0
,
0
,
0
,
58
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
25
,
0
,
0
,
0
,
82
,
0
,
0
,
0
,
33
,
0
,
0
,
0
,
90
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
2
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
2
1
,
0
,
0
,
0
,
90
,
0
,
0
,
0
,
2
9
,
0
,
0
,
0
,
106
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
112
,
101
,
114
,
109
,
97
,
110
,
101
,
11
0
,
116
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
116
,
101
,
109
,
112
,
111
,
114
,
97
,
114
,
1
21
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
3
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
25
,
0
,
0
,
0
,
114
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
02
,
97
,
105
,
108
,
101
,
10
0
,
0
,
0
,
111
,
118
,
101
,
114
,
108
,
111
,
97
,
100
,
101
,
100
,
0
,
0
,
0
,
0
,
0
,
0
,
}
101
,
100
,
0
,
0
,
0
,
0
,
0
,
0
,
100
,
105
,
115
,
99
,
111
,
110
,
110
,
101
,
99
,
116
,
101
,
100
,
0
,
0
,
0
,
0
,
117
,
110
,
105
,
109
,
112
,
108
,
101
,
109
,
101
,
110
,
116
,
101
,
100
,
0
,
0
,
0
,
}
};
::
capnp
::
word
const
*
const
bp_b
baeda2607b6f958
=
b_bbaeda2607b6f9
58
.
words
;
::
capnp
::
word
const
*
const
bp_b
28c96e23f4cbd58
=
b_b28c96e23f4cbd
58
.
words
;
#if !CAPNP_LITE
static
const
uint16_t
m_b
baeda2607b6f958
[]
=
{
2
,
0
,
1
};
const
::
capnp
::
_
::
RawSchema
s_b
baeda2607b6f9
58
=
{
0xb
baeda2607b6f958
,
b_bbaeda2607b6f958
.
words
,
34
,
nullptr
,
m_bbaeda2607b6f9
58
,
0
,
3
,
nullptr
,
nullptr
,
nullptr
,
{
&
s_bbaeda2607b6f9
58
,
nullptr
,
nullptr
,
0
,
0
,
nullptr
}
static
const
uint16_t
m_b
28c96e23f4cbd58
[]
=
{
2
,
0
,
1
,
3
};
const
::
capnp
::
_
::
RawSchema
s_b
28c96e23f4cbd
58
=
{
0xb
28c96e23f4cbd58
,
b_b28c96e23f4cbd58
.
words
,
37
,
nullptr
,
m_b28c96e23f4cbd
58
,
0
,
4
,
nullptr
,
nullptr
,
nullptr
,
{
&
s_b28c96e23f4cbd
58
,
nullptr
,
nullptr
,
0
,
0
,
nullptr
}
};
#endif // !CAPNP_LITE
CAPNP_DEFINE_ENUM
(
Durability_bbaeda2607b6f958
,
bbaeda2607b6f9
58
);
CAPNP_DEFINE_ENUM
(
Type_b28c96e23f4cbd58
,
b28c96e23f4cbd
58
);
}
// namespace schemas
}
// namespace capnp
...
...
c++/src/capnp/rpc.capnp.h
View file @
0af31360
...
...
@@ -34,13 +34,14 @@ CAPNP_DECLARE_SCHEMA(d800b1d6cd6f1ca0);
CAPNP_DECLARE_SCHEMA
(
f316944415569081
);
CAPNP_DECLARE_SCHEMA
(
d37007fde1f0027d
);
CAPNP_DECLARE_SCHEMA
(
d625b7063acf691a
);
CAPNP_DECLARE_SCHEMA
(
bbaeda2607b6f958
);
enum
class
Durability_bbaeda2607b6f958
:
uint16_t
{
PERMANENT
,
TEMPORARY
,
CAPNP_DECLARE_SCHEMA
(
b28c96e23f4cbd58
);
enum
class
Type_b28c96e23f4cbd58
:
uint16_t
{
FAILED
,
OVERLOADED
,
DISCONNECTED
,
UNIMPLEMENTED
,
};
CAPNP_DECLARE_ENUM
(
Durability
,
bbaeda2607b6f9
58
);
CAPNP_DECLARE_ENUM
(
Type
,
b28c96e23f4cbd
58
);
}
// namespace schemas
}
// namespace capnp
...
...
@@ -397,7 +398,7 @@ struct Exception {
class
Reader
;
class
Builder
;
class
Pipeline
;
typedef
::
capnp
::
schemas
::
Durability_bbaeda2607b6f958
Durability
;
typedef
::
capnp
::
schemas
::
Type_b28c96e23f4cbd58
Type
;
struct
_capnpPrivate
{
...
...
@@ -2390,9 +2391,11 @@ public:
inline
bool
hasReason
()
const
;
inline
::
capnp
::
Text
::
Reader
getReason
()
const
;
inline
bool
getIsCallersFault
()
const
;
inline
bool
get
Obsolete
IsCallersFault
()
const
;
inline
::
capnp
::
rpc
::
Exception
::
Durability
getDurability
()
const
;
inline
::
uint16_t
getObsoleteDurability
()
const
;
inline
::
capnp
::
rpc
::
Exception
::
Type
getType
()
const
;
private
:
::
capnp
::
_
::
StructReader
_reader
;
...
...
@@ -2429,11 +2432,14 @@ public:
inline
void
adoptReason
(
::
capnp
::
Orphan
<
::
capnp
::
Text
>&&
value
);
inline
::
capnp
::
Orphan
<
::
capnp
::
Text
>
disownReason
();
inline
bool
getIsCallersFault
();
inline
void
setIsCallersFault
(
bool
value
);
inline
bool
getObsoleteIsCallersFault
();
inline
void
setObsoleteIsCallersFault
(
bool
value
);
inline
::
uint16_t
getObsoleteDurability
();
inline
void
setObsoleteDurability
(
::
uint16_t
value
);
inline
::
capnp
::
rpc
::
Exception
::
Durability
getDurability
();
inline
void
set
Durability
(
::
capnp
::
rpc
::
Exception
::
Durability
value
);
inline
::
capnp
::
rpc
::
Exception
::
Type
getType
();
inline
void
set
Type
(
::
capnp
::
rpc
::
Exception
::
Type
value
);
private
:
::
capnp
::
_
::
StructBuilder
_builder
;
...
...
@@ -4754,34 +4760,48 @@ inline ::capnp::Orphan< ::capnp::Text> Exception::Builder::disownReason() {
_builder
.
getPointerField
(
0
*
::
capnp
::
POINTERS
));
}
inline
bool
Exception
::
Reader
::
getIsCallersFault
()
const
{
inline
bool
Exception
::
Reader
::
get
Obsolete
IsCallersFault
()
const
{
return
_reader
.
getDataField
<
bool
>
(
0
*
::
capnp
::
ELEMENTS
);
}
inline
bool
Exception
::
Builder
::
getIsCallersFault
()
{
inline
bool
Exception
::
Builder
::
get
Obsolete
IsCallersFault
()
{
return
_builder
.
getDataField
<
bool
>
(
0
*
::
capnp
::
ELEMENTS
);
}
inline
void
Exception
::
Builder
::
setIsCallersFault
(
bool
value
)
{
inline
void
Exception
::
Builder
::
set
Obsolete
IsCallersFault
(
bool
value
)
{
_builder
.
setDataField
<
bool
>
(
0
*
::
capnp
::
ELEMENTS
,
value
);
}
inline
::
capnp
::
rpc
::
Exception
::
Durability
Exception
::
Reader
::
get
Durability
()
const
{
return
_reader
.
getDataField
<
::
capnp
::
rpc
::
Exception
::
Durability
>
(
inline
::
uint16_t
Exception
::
Reader
::
getObsolete
Durability
()
const
{
return
_reader
.
getDataField
<
::
uint16_t
>
(
1
*
::
capnp
::
ELEMENTS
);
}
inline
::
capnp
::
rpc
::
Exception
::
Durability
Exception
::
Builder
::
get
Durability
()
{
return
_builder
.
getDataField
<
::
capnp
::
rpc
::
Exception
::
Durability
>
(
inline
::
uint16_t
Exception
::
Builder
::
getObsolete
Durability
()
{
return
_builder
.
getDataField
<
::
uint16_t
>
(
1
*
::
capnp
::
ELEMENTS
);
}
inline
void
Exception
::
Builder
::
set
Durability
(
::
capnp
::
rpc
::
Exception
::
Durability
value
)
{
_builder
.
setDataField
<
::
capnp
::
rpc
::
Exception
::
Durability
>
(
inline
void
Exception
::
Builder
::
set
ObsoleteDurability
(
::
uint16_t
value
)
{
_builder
.
setDataField
<
::
uint16_t
>
(
1
*
::
capnp
::
ELEMENTS
,
value
);
}
inline
::
capnp
::
rpc
::
Exception
::
Type
Exception
::
Reader
::
getType
()
const
{
return
_reader
.
getDataField
<
::
capnp
::
rpc
::
Exception
::
Type
>
(
2
*
::
capnp
::
ELEMENTS
);
}
inline
::
capnp
::
rpc
::
Exception
::
Type
Exception
::
Builder
::
getType
()
{
return
_builder
.
getDataField
<
::
capnp
::
rpc
::
Exception
::
Type
>
(
2
*
::
capnp
::
ELEMENTS
);
}
inline
void
Exception
::
Builder
::
setType
(
::
capnp
::
rpc
::
Exception
::
Type
value
)
{
_builder
.
setDataField
<
::
capnp
::
rpc
::
Exception
::
Type
>
(
2
*
::
capnp
::
ELEMENTS
,
value
);
}
}
// namespace
}
// namespace
...
...
c++/src/capnp/schema-parser.c++
View file @
0af31360
...
...
@@ -462,8 +462,8 @@ public:
void
reportError
(
SourcePos
start
,
SourcePos
end
,
kj
::
StringPtr
message
)
const
override
{
kj
::
getExceptionCallback
().
onRecoverableException
(
kj
::
Exception
(
kj
::
Exception
::
Nature
::
LOCAL_BUG
,
kj
::
Exception
::
Durability
::
PERMANENT
,
kj
::
heapString
(
diskPath
),
start
.
line
,
kj
::
heapString
(
message
)));
kj
::
Exception
::
Type
::
FAILED
,
kj
::
heapString
(
diskPath
),
start
.
line
,
kj
::
heapString
(
message
)));
}
private
:
...
...
c++/src/kj/async-inl.h
View file @
0af31360
...
...
@@ -828,9 +828,7 @@ private:
delete
this
;
}
else
{
if
(
inner
->
isWaiting
())
{
inner
->
reject
(
kj
::
Exception
(
kj
::
Exception
::
Nature
::
LOCAL_BUG
,
kj
::
Exception
::
Durability
::
PERMANENT
,
__FILE__
,
__LINE__
,
inner
->
reject
(
kj
::
Exception
(
kj
::
Exception
::
Type
::
FAILED
,
__FILE__
,
__LINE__
,
kj
::
heapString
(
"PromiseFulfiller was destroyed without fulfilling the promise."
)));
}
inner
=
nullptr
;
...
...
c++/src/kj/common.c++
View file @
0af31360
...
...
@@ -32,21 +32,10 @@ namespace _ { // private
void
inlineRequireFailure
(
const
char
*
file
,
int
line
,
const
char
*
expectation
,
const
char
*
macroArgs
,
const
char
*
message
)
{
if
(
message
==
nullptr
)
{
Debug
::
Fault
f
(
file
,
line
,
Exception
::
Nature
::
PRECONDITION
,
0
,
expectation
,
macroArgs
);
Debug
::
Fault
f
(
file
,
line
,
0
,
expectation
,
macroArgs
);
f
.
fatal
();
}
else
{
Debug
::
Fault
f
(
file
,
line
,
Exception
::
Nature
::
PRECONDITION
,
0
,
expectation
,
macroArgs
,
message
);
f
.
fatal
();
}
}
void
inlineAssertFailure
(
const
char
*
file
,
int
line
,
const
char
*
expectation
,
const
char
*
macroArgs
,
const
char
*
message
)
{
if
(
message
==
nullptr
)
{
Debug
::
Fault
f
(
file
,
line
,
Exception
::
Nature
::
LOCAL_BUG
,
0
,
expectation
,
macroArgs
);
f
.
fatal
();
}
else
{
Debug
::
Fault
f
(
file
,
line
,
Exception
::
Nature
::
LOCAL_BUG
,
0
,
expectation
,
macroArgs
,
message
);
Debug
::
Fault
f
(
file
,
line
,
0
,
expectation
,
macroArgs
,
message
);
f
.
fatal
();
}
}
...
...
c++/src/kj/common.h
View file @
0af31360
...
...
@@ -185,9 +185,6 @@ namespace _ { // private
KJ_NORETURN
(
void
inlineRequireFailure
(
const
char
*
file
,
int
line
,
const
char
*
expectation
,
const
char
*
macroArgs
,
const
char
*
message
=
nullptr
));
KJ_NORETURN
(
void
inlineAssertFailure
(
const
char
*
file
,
int
line
,
const
char
*
expectation
,
const
char
*
macroArgs
,
const
char
*
message
=
nullptr
));
KJ_NORETURN
(
void
unreachable
());
...
...
@@ -195,20 +192,13 @@ KJ_NORETURN(void unreachable());
#ifdef KJ_DEBUG
#if _MSC_VER
// TODO(msvc): Figure out __VA_ARGS__; see debug.h.
#define KJ_IREQUIRE(condition, ...) \
if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \
__FILE__, __LINE__, #condition, "")
__FILE__, __LINE__, #condition, ""
#__VA_ARGS__, __VA_ARGS__
)
// Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to
// check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that
// it will be enabled depending on whether the application is compiled in debug mode rather than
// whether libkj is.
#define KJ_IASSERT(condition, ...) \
if (KJ_LIKELY(condition)); else ::kj::_::inlineAssertFailure( \
__FILE__, __LINE__, #condition, "")
// Version of KJ_DASSERT() which is safe to use in headers that are #included by users. Used to
// check state inside inline and templated methods.
#else
#define KJ_IREQUIRE(condition, ...) \
if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \
...
...
@@ -217,18 +207,13 @@ KJ_NORETURN(void unreachable());
// check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that
// it will be enabled depending on whether the application is compiled in debug mode rather than
// whether libkj is.
#define KJ_IASSERT(condition, ...) \
if (KJ_LIKELY(condition)); else ::kj::_::inlineAssertFailure( \
__FILE__, __LINE__, #condition, #__VA_ARGS__, ##__VA_ARGS__)
// Version of KJ_DASSERT() which is safe to use in headers that are #included by users. Used to
// check state inside inline and templated methods.
#endif
#else
#define KJ_IREQUIRE(condition, ...)
#define KJ_IASSERT(condition, ...)
#endif
#define KJ_IASSERT KJ_IREQUIRE
#define KJ_UNREACHABLE ::kj::_::unreachable();
// Put this on code paths that cannot be reached to suppress compiler warnings about missing
// returns.
...
...
c++/src/kj/debug-test.c++
View file @
0af31360
...
...
@@ -233,7 +233,7 @@ TEST(Debug, Log) {
KJ_ASSERT
(
1
==
1
);
EXPECT_FATAL
(
KJ_ASSERT
(
1
==
2
));
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
":
bug in code
: expected "
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
":
failed
: expected "
"1 == 2
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
...
...
@@ -244,27 +244,38 @@ TEST(Debug, Log) {
bool
recovered
=
false
;
KJ_ASSERT
(
1
==
2
,
"1 is not 2"
)
{
recovered
=
true
;
break
;
}
line
=
__LINE__
;
EXPECT_EQ
(
"recoverable exception: "
+
fileLine
(
__FILE__
,
line
)
+
":
bug in code
: expected "
EXPECT_EQ
(
"recoverable exception: "
+
fileLine
(
__FILE__
,
line
)
+
":
failed
: expected "
"1 == 2; 1 is not 2
\n
"
,
mockCallback
.
text
);
EXPECT_TRUE
(
recovered
);
mockCallback
.
text
.
clear
();
EXPECT_FATAL
(
KJ_ASSERT
(
1
==
2
,
i
,
"hi"
,
str
));
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
":
bug in code
: expected "
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
":
failed
: expected "
"1 == 2; i = 123; hi; str = foo
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
EXPECT_FATAL
(
KJ_REQUIRE
(
1
==
2
,
i
,
"hi"
,
str
));
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
":
requirement not met
: expected "
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
":
failed
: expected "
"1 == 2; i = 123; hi; str = foo
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
EXPECT_FATAL
(
KJ_FAIL_ASSERT
(
"foo"
));
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
":
bug in code
: foo
\n
"
,
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
":
failed
: foo
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
}
TEST
(
Debug
,
Exception
)
{
int
i
=
123
;
int
line
=
__LINE__
;
Exception
exception
=
KJ_EXCEPTION
(
DISCONNECTED
,
"foo"
,
i
);
EXPECT_EQ
(
Exception
::
Type
::
DISCONNECTED
,
exception
.
getType
());
EXPECT_STREQ
(
__FILE__
,
exception
.
getFile
());
EXPECT_EQ
(
line
,
exception
.
getLine
());
EXPECT_EQ
(
"foo; i = 123"
,
exception
.
getDescription
());
}
TEST
(
Debug
,
Catch
)
{
int
line
;
...
...
@@ -280,7 +291,7 @@ TEST(Debug, Catch) {
what
=
kj
::
str
(
what
.
slice
(
0
,
*
eol
));
}
std
::
string
text
(
what
.
cStr
());
EXPECT_EQ
(
fileLine
(
__FILE__
,
line
)
+
":
bug in code
: foo"
,
text
);
EXPECT_EQ
(
fileLine
(
__FILE__
,
line
)
+
":
failed
: foo"
,
text
);
}
else
{
ADD_FAILURE
()
<<
"Expected exception."
;
}
...
...
@@ -299,7 +310,7 @@ TEST(Debug, Catch) {
what
=
kj
::
str
(
what
.
slice
(
0
,
*
eol
));
}
std
::
string
text
(
what
.
cStr
());
EXPECT_EQ
(
fileLine
(
__FILE__
,
line
)
+
":
bug in code
: foo"
,
text
);
EXPECT_EQ
(
fileLine
(
__FILE__
,
line
)
+
":
failed
: foo"
,
text
);
}
else
{
ADD_FAILURE
()
<<
"Expected exception."
;
}
...
...
@@ -318,7 +329,7 @@ TEST(Debug, Catch) {
}
else
{
text
.
assign
(
what
.
cStr
());
}
EXPECT_EQ
(
fileLine
(
__FILE__
,
line
)
+
":
bug in code
: foo"
,
text
);
EXPECT_EQ
(
fileLine
(
__FILE__
,
line
)
+
":
failed
: foo"
,
text
);
}
}
#endif
...
...
@@ -329,11 +340,6 @@ int mockSyscall(int i, int error = 0) {
return
i
;
}
int
fail
()
{
errno
=
EBADF
;
return
-
1
;
}
TEST
(
Debug
,
Syscall
)
{
MockExceptionCallback
mockCallback
;
int
line
;
...
...
@@ -346,7 +352,25 @@ TEST(Debug, Syscall) {
EXPECT_FATAL
(
KJ_SYSCALL
(
mockSyscall
(
-
1
,
EBADF
),
i
,
"bar"
,
str
));
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
": error from OS: mockSyscall(-1, EBADF): "
+
strerror
(
EBADF
)
+
": failed: mockSyscall(-1, EBADF): "
+
strerror
(
EBADF
)
+
"; i = 123; bar; str = foo
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
EXPECT_FATAL
(
KJ_SYSCALL
(
mockSyscall
(
-
1
,
ECONNRESET
),
i
,
"bar"
,
str
));
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
": disconnected: mockSyscall(-1, ECONNRESET): "
+
strerror
(
ECONNRESET
)
+
"; i = 123; bar; str = foo
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
EXPECT_FATAL
(
KJ_SYSCALL
(
mockSyscall
(
-
1
,
ENOMEM
),
i
,
"bar"
,
str
));
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
": overloaded: mockSyscall(-1, ENOMEM): "
+
strerror
(
ENOMEM
)
+
"; i = 123; bar; str = foo
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
EXPECT_FATAL
(
KJ_SYSCALL
(
mockSyscall
(
-
1
,
ENOSYS
),
i
,
"bar"
,
str
));
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
line
)
+
": unimplemented: mockSyscall(-1, ENOSYS): "
+
strerror
(
ENOSYS
)
+
"; i = 123; bar; str = foo
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
...
...
@@ -354,9 +378,9 @@ TEST(Debug, Syscall) {
bool
recovered
=
false
;
KJ_SYSCALL
(
result
=
mockSyscall
(
-
2
,
EBADF
),
i
,
"bar"
,
str
)
{
recovered
=
true
;
break
;
}
line
=
__LINE__
;
EXPECT_EQ
(
"recoverable exception: "
+
fileLine
(
__FILE__
,
line
)
+
":
error from OS
: mockSyscall(-2, EBADF): "
+
strerror
(
EBADF
)
+
":
failed
: mockSyscall(-2, EBADF): "
+
strerror
(
EBADF
)
+
"; i = 123; bar; str = foo
\n
"
,
mockCallback
.
text
);
EXPECT_
LT
(
result
,
0
);
EXPECT_
EQ
(
-
2
,
result
);
EXPECT_TRUE
(
recovered
);
}
...
...
@@ -374,7 +398,7 @@ TEST(Debug, Context) {
EXPECT_FATAL
(
KJ_FAIL_ASSERT
(
"bar"
));
line
=
__LINE__
;
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
cline
)
+
": context: foo
\n
"
+
fileLine
(
__FILE__
,
line
)
+
":
bug in code
: bar
\n
"
,
+
fileLine
(
__FILE__
,
line
)
+
":
failed
: bar
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
...
...
@@ -386,7 +410,7 @@ TEST(Debug, Context) {
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
cline
)
+
": context: foo
\n
"
+
fileLine
(
__FILE__
,
cline2
)
+
": context: baz; i = 123; corge; str = qux
\n
"
+
fileLine
(
__FILE__
,
line
)
+
":
bug in code
: bar
\n
"
,
+
fileLine
(
__FILE__
,
line
)
+
":
failed
: bar
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
}
...
...
@@ -397,7 +421,7 @@ TEST(Debug, Context) {
EXPECT_EQ
(
"fatal exception: "
+
fileLine
(
__FILE__
,
cline
)
+
": context: foo
\n
"
+
fileLine
(
__FILE__
,
cline2
)
+
": context: grault
\n
"
+
fileLine
(
__FILE__
,
line
)
+
":
bug in code
: bar
\n
"
,
+
fileLine
(
__FILE__
,
line
)
+
":
failed
: bar
\n
"
,
mockCallback
.
text
);
mockCallback
.
text
.
clear
();
}
...
...
c++/src/kj/debug.c++
View file @
0af31360
...
...
@@ -49,14 +49,53 @@ ArrayPtr<const char> KJ_STRINGIFY(Debug::Severity severity) {
namespace
{
Exception
::
Type
typeOfErrno
(
int
error
)
{
switch
(
error
)
{
case
EDQUOT
:
case
EMFILE
:
case
ENFILE
:
case
ENOBUFS
:
case
ENOLCK
:
case
ENOMEM
:
case
ENOSPC
:
case
ETIMEDOUT
:
case
EUSERS
:
return
Exception
::
Type
::
OVERLOADED
;
case
ECONNABORTED
:
case
ECONNREFUSED
:
case
ECONNRESET
:
case
EHOSTDOWN
:
case
EHOSTUNREACH
:
case
ENETDOWN
:
case
ENETRESET
:
case
ENETUNREACH
:
case
ENONET
:
case
EPIPE
:
return
Exception
::
Type
::
DISCONNECTED
;
case
ENOSYS
:
#if ENOTSUP
case
ENOTSUP
:
#endif
#if EOPNOTSUPP && EOPNOTSUPP != ENOTSUP
case
EOPNOTSUPP
:
#endif
return
Exception
::
Type
::
UNIMPLEMENTED
;
default
:
return
Exception
::
Type
::
FAILED
;
}
}
enum
DescriptionStyle
{
LOG
,
ASSERTION
,
SYSCALL
};
static
String
makeDescription
(
DescriptionStyle
style
,
const
char
*
code
,
int
errorNumber
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
static
String
makeDescription
Impl
(
DescriptionStyle
style
,
const
char
*
code
,
int
errorNumber
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
KJ_STACK_ARRAY
(
ArrayPtr
<
const
char
>
,
argNames
,
argValues
.
size
(),
8
,
64
);
if
(
argValues
.
size
()
>
0
)
{
...
...
@@ -193,7 +232,7 @@ static String makeDescription(DescriptionStyle style, const char* code, int erro
void
Debug
::
logInternal
(
const
char
*
file
,
int
line
,
Severity
severity
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
getExceptionCallback
().
logMessage
(
file
,
line
,
0
,
str
(
severity
,
": "
,
makeDescription
(
LOG
,
nullptr
,
0
,
macroArgs
,
argValues
),
'\n'
));
str
(
severity
,
": "
,
makeDescription
Impl
(
LOG
,
nullptr
,
0
,
macroArgs
,
argValues
),
'\n'
));
}
Debug
::
Fault
::~
Fault
()
noexcept
(
false
)
{
...
...
@@ -213,15 +252,15 @@ void Debug::Fault::fatal() {
}
void
Debug
::
Fault
::
init
(
const
char
*
file
,
int
line
,
Exception
::
Nature
nature
,
int
e
rrorNumber
,
const
char
*
file
,
int
line
,
int
osE
rrorNumber
,
const
char
*
condition
,
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
exception
=
new
Exception
(
nature
,
Exception
::
Durability
::
PERMANENT
,
file
,
line
,
makeDescription
(
nature
==
Exception
::
Nature
::
OS_ERROR
?
SYSCALL
:
ASSERTION
,
condition
,
e
rrorNumber
,
macroArgs
,
argValues
));
exception
=
new
Exception
(
typeOfErrno
(
osErrorNumber
)
,
file
,
line
,
makeDescription
Impl
(
osErrorNumber
!=
0
?
SYSCALL
:
ASSERTION
,
condition
,
osE
rrorNumber
,
macroArgs
,
argValues
));
}
String
Debug
::
make
Context
DescriptionInternal
(
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
return
makeDescription
(
LOG
,
nullptr
,
0
,
macroArgs
,
argValues
);
String
Debug
::
makeDescriptionInternal
(
const
char
*
macroArgs
,
ArrayPtr
<
String
>
argValues
)
{
return
makeDescription
Impl
(
LOG
,
nullptr
,
0
,
macroArgs
,
argValues
);
}
int
Debug
::
getOsErrorNumber
(
bool
nonblocking
)
{
...
...
c++/src/kj/debug.h
View file @
0af31360
This diff is collapsed.
Click to expand it.
c++/src/kj/exception.c++
View file @
0af31360
...
...
@@ -26,6 +26,7 @@
#include "miniposix.h"
#include <stdlib.h>
#include <exception>
#include <new>
#if (__linux__ && !__ANDROID__) || __APPLE__
#define KJ_HAS_BACKTRACE 1
...
...
@@ -122,27 +123,15 @@ String getStackSymbols(ArrayPtr<void* const> trace) {
}
// namespace
ArrayPtr
<
const
char
>
KJ_STRINGIFY
(
Exception
::
Nature
nature
)
{
static
const
char
*
NATURE_STRINGS
[]
=
{
"requirement not met"
,
"bug in code"
,
"error from OS"
,
"network failure"
,
"error"
ArrayPtr
<
const
char
>
KJ_STRINGIFY
(
Exception
::
Type
type
)
{
static
const
char
*
TYPE_STRINGS
[]
=
{
"failed"
,
"overloaded"
,
"disconnected"
,
"unimplemented"
};
const
char
*
s
=
NATURE_STRINGS
[
static_cast
<
uint
>
(
nature
)];
return
arrayPtr
(
s
,
strlen
(
s
));
}
ArrayPtr
<
const
char
>
KJ_STRINGIFY
(
Exception
::
Durability
durability
)
{
static
const
char
*
DURABILITY_STRINGS
[]
=
{
"permanent"
,
"temporary"
,
"overloaded"
};
const
char
*
s
=
DURABILITY_STRINGS
[
static_cast
<
uint
>
(
durability
)];
const
char
*
s
=
TYPE_STRINGS
[
static_cast
<
uint
>
(
type
)];
return
arrayPtr
(
s
,
strlen
(
s
));
}
...
...
@@ -174,17 +163,14 @@ String KJ_STRINGIFY(const Exception& e) {
}
return
str
(
strArray
(
contextText
,
""
),
e
.
getFile
(),
":"
,
e
.
getLine
(),
": "
,
e
.
getNature
(),
e
.
getDurability
()
==
Exception
::
Durability
::
TEMPORARY
?
" (temporary)"
:
""
,
e
.
getFile
(),
":"
,
e
.
getLine
(),
": "
,
e
.
getType
(),
e
.
getDescription
()
==
nullptr
?
""
:
": "
,
e
.
getDescription
(),
e
.
getStackTrace
().
size
()
>
0
?
"
\n
stack: "
:
""
,
strArray
(
e
.
getStackTrace
(),
" "
),
getStackSymbols
(
e
.
getStackTrace
()));
}
Exception
::
Exception
(
Nature
nature
,
Durability
durability
,
const
char
*
file
,
int
line
,
String
description
)
noexcept
:
file
(
file
),
line
(
line
),
nature
(
nature
),
durability
(
durability
),
description
(
mv
(
description
))
{
Exception
::
Exception
(
Type
type
,
const
char
*
file
,
int
line
,
String
description
)
noexcept
:
file
(
file
),
line
(
line
),
type
(
type
),
description
(
mv
(
description
))
{
#ifndef KJ_HAS_BACKTRACE
traceCount
=
0
;
#else
...
...
@@ -192,10 +178,9 @@ Exception::Exception(Nature nature, Durability durability, const char* file, int
#endif
}
Exception
::
Exception
(
Nature
nature
,
Durability
durability
,
String
file
,
int
line
,
String
description
)
noexcept
:
ownFile
(
kj
::
mv
(
file
)),
file
(
ownFile
.
cStr
()),
line
(
line
),
nature
(
nature
),
durability
(
durability
),
description
(
mv
(
description
))
{
Exception
::
Exception
(
Type
type
,
String
file
,
int
line
,
String
description
)
noexcept
:
ownFile
(
kj
::
mv
(
file
)),
file
(
ownFile
.
cStr
()),
line
(
line
),
type
(
type
),
description
(
mv
(
description
))
{
#ifndef KJ_HAS_BACKTRACE
traceCount
=
0
;
#else
...
...
@@ -204,7 +189,7 @@ Exception::Exception(Nature nature, Durability durability, String file, int line
}
Exception
::
Exception
(
const
Exception
&
other
)
noexcept
:
file
(
other
.
file
),
line
(
other
.
line
),
nature
(
other
.
nature
),
durability
(
other
.
durability
),
:
file
(
other
.
file
),
line
(
other
.
line
),
type
(
other
.
type
),
description
(
heapString
(
other
.
description
)),
traceCount
(
other
.
traceCount
)
{
if
(
file
==
other
.
ownFile
.
cStr
())
{
ownFile
=
heapString
(
other
.
ownFile
);
...
...
@@ -334,8 +319,7 @@ private:
// We intentionally don't log the context since it should get re-added by the exception callback
// anyway.
getExceptionCallback
().
logMessage
(
e
.
getFile
(),
e
.
getLine
(),
0
,
str
(
e
.
getNature
(),
e
.
getDurability
()
==
Exception
::
Durability
::
TEMPORARY
?
" (temporary)"
:
""
,
e
.
getDescription
()
==
nullptr
?
""
:
": "
,
e
.
getDescription
(),
e
.
getType
(),
e
.
getDescription
()
==
nullptr
?
""
:
": "
,
e
.
getDescription
(),
e
.
getStackTrace
().
size
()
>
0
?
"
\n
stack: "
:
""
,
strArray
(
e
.
getStackTrace
(),
" "
),
getStackSymbols
(
e
.
getStackTrace
()),
"
\n
"
));
}
...
...
@@ -404,17 +388,17 @@ uint uncaughtExceptionCount() {
// https://github.com/panaseleus/stack_unwinding/blob/master/boost/exception/uncaught_exception_count.hpp
// Alas, it doesn not appera to work on MSVC2015. The linker claims _getptd() doesn't exist.
extern "C" char *__cdecl _getptd();
uint uncaughtExceptionCount() {
return *reinterpret_cast<uint*>(_getptd() + (sizeof(void*) == 8 ? 0x100 : 0x90));
extern "C" char *__cdecl _getptd();
uint uncaughtExceptionCount() {
return *reinterpret_cast<uint*>(_getptd() + (sizeof(void*) == 8 ? 0x100 : 0x90));
}
#endif
uint
uncaughtExceptionCount
()
{
// Since the above doesn't work, fall back to uncaught_exception(). This will produce incorrect
// results in very obscure cases that Cap'n Proto doesn't really rely on anyway.
return
std
::
uncaught_exception
();
uint
uncaughtExceptionCount
()
{
// Since the above doesn't work, fall back to uncaught_exception(). This will produce incorrect
// results in very obscure cases that Cap'n Proto doesn't really rely on anyway.
return
std
::
uncaught_exception
();
}
#else
...
...
@@ -467,11 +451,14 @@ Maybe<Exception> runCatchingExceptions(Runnable& runnable) noexcept {
return
nullptr
;
}
catch
(
Exception
&
e
)
{
return
kj
::
mv
(
e
);
}
catch
(
std
::
bad_alloc
&
e
)
{
return
Exception
(
Exception
::
Type
::
OVERLOADED
,
"(unknown)"
,
-
1
,
str
(
"std::bad_alloc: "
,
e
.
what
()));
}
catch
(
std
::
exception
&
e
)
{
return
Exception
(
Exception
::
Nature
::
OTHER
,
Exception
::
Durability
::
PERMANENT
,
return
Exception
(
Exception
::
Type
::
FAILED
,
"(unknown)"
,
-
1
,
str
(
"std::exception: "
,
e
.
what
()));
}
catch
(...)
{
return
Exception
(
Exception
::
Nature
::
OTHER
,
Exception
::
Durability
::
PERMANENT
,
return
Exception
(
Exception
::
Type
::
FAILED
,
"(unknown)"
,
-
1
,
str
(
"Unknown non-KJ exception."
));
}
#endif
...
...
c++/src/kj/exception.h
View file @
0af31360
...
...
@@ -40,50 +40,44 @@ class Exception {
// Actually, a subclass of this which also implements std::exception will be thrown, but we hide
// that fact from the interface to avoid #including <exception>.
#ifdef __CDT_PARSER__
// For some reason Eclipse gets confused by the definition of Nature if it's the first thing
// in the class.
typedef
void
WorkAroundCdtBug
;
#endif
public
:
enum
class
Nature
{
// What kind of failure? This is informational, not intended for programmatic use.
// Note that the difference between some of these failure types is not always clear. For
// example, a precondition failure may be due to a "local bug" in the calling code, or it
// may be due to invalid input.
PRECONDITION
,
LOCAL_BUG
,
OS_ERROR
,
NETWORK_FAILURE
,
OTHER
// Make sure to update the stringifier if you add a new nature.
};
enum
class
Durability
{
PERMANENT
,
// Retrying the exact same operation will fail in exactly the same way.
TEMPORARY
,
// Retrying the exact same operation might succeed.
OVERLOADED
// The error was possibly caused by the system being overloaded. Retrying the
// operation might work at a later point in time, but the caller should NOT retry
// immediately as this will probably exacerbate the problem.
// Make sure to update the stringifier if you add a new durability.
enum
class
Type
{
// What kind of failure?
FAILED
=
0
,
// Something went wrong. This is the usual error type. KJ_ASSERT and KJ_REQUIRE throw this
// error type.
OVERLOADED
=
1
,
// The call failed because of a temporary lack of resources. This could be space resources
// (out of memory, out of disk space) or time resources (request queue overflow, operation
// timed out).
//
// The operation might work if tried again, but it should NOT be repeated immediately as this
// may simply exacerbate the problem.
DISCONNECTED
=
2
,
// The call required communication over a connection that has been lost. The callee will need
// to re-establish connections and try again.
UNIMPLEMENTED
=
3
// The requested method is not implemented. The caller may wish to revert to a fallback
// approach based on other methods.
// IF YOU ADD A NEW VALUE:
// - Update the stringifier.
// - Update Cap'n Proto's RPC protocol's Exception.Type enum.
};
Exception
(
Nature
nature
,
Durability
durability
,
const
char
*
file
,
int
line
,
String
description
=
nullptr
)
noexcept
;
Exception
(
Nature
nature
,
Durability
durability
,
String
file
,
int
line
,
String
description
=
nullptr
)
noexcept
;
Exception
(
Type
type
,
const
char
*
file
,
int
line
,
String
description
=
nullptr
)
noexcept
;
Exception
(
Type
type
,
String
file
,
int
line
,
String
description
=
nullptr
)
noexcept
;
Exception
(
const
Exception
&
other
)
noexcept
;
Exception
(
Exception
&&
other
)
=
default
;
~
Exception
()
noexcept
;
const
char
*
getFile
()
const
{
return
file
;
}
int
getLine
()
const
{
return
line
;
}
Nature
getNature
()
const
{
return
nature
;
}
Durability
getDurability
()
const
{
return
durability
;
}
Type
getType
()
const
{
return
type
;
}
StringPtr
getDescription
()
const
{
return
description
;
}
ArrayPtr
<
void
*
const
>
getStackTrace
()
const
{
return
arrayPtr
(
trace
,
traceCount
);
}
...
...
@@ -117,8 +111,7 @@ private:
String
ownFile
;
const
char
*
file
;
int
line
;
Nature
nature
;
Durability
durability
;
Type
type
;
String
description
;
Maybe
<
Own
<
Context
>>
context
;
void
*
trace
[
16
];
...
...
@@ -128,8 +121,7 @@ private:
};
// TODO(soon): These should return StringPtr.
ArrayPtr
<
const
char
>
KJ_STRINGIFY
(
Exception
::
Nature
nature
);
ArrayPtr
<
const
char
>
KJ_STRINGIFY
(
Exception
::
Durability
durability
);
ArrayPtr
<
const
char
>
KJ_STRINGIFY
(
Exception
::
Type
type
);
String
KJ_STRINGIFY
(
const
Exception
&
e
);
// =======================================================================================
...
...
c++/src/kj/time.c++
View file @
0af31360
...
...
@@ -26,9 +26,7 @@
namespace
kj
{
kj
::
Exception
Timer
::
makeTimeoutException
()
{
return
kj
::
Exception
(
kj
::
Exception
::
Nature
::
LOCAL_BUG
,
kj
::
Exception
::
Durability
::
OVERLOADED
,
__FILE__
,
__LINE__
,
kj
::
heapString
(
"operation timed out"
));
return
KJ_EXCEPTION
(
OVERLOADED
,
"operation timed out"
);
}
}
// namespace kj
c++/src/kj/time.h
View file @
0af31360
...
...
@@ -84,12 +84,14 @@ public:
template
<
typename
T
>
Promise
<
T
>
timeoutAt
(
TimePoint
time
,
Promise
<
T
>&&
promise
);
// Return a promise equivalent to `promise` but which throws an exception (and cancels the
// original promise) if it hasn't completed by `time`.
// original promise) if it hasn't completed by `time`. The thrown exception is of type
// "OVERLOADED".
template
<
typename
T
>
Promise
<
T
>
timeoutAfter
(
Duration
delay
,
Promise
<
T
>&&
promise
);
// Return a promise equivalent to `promise` but which throws an exception (and cancels the
// original promise) if it hasn't completed after `delay` from now.
// original promise) if it hasn't completed after `delay` from now. The thrown exception is of
// type "OVERLOADED".
private
:
static
kj
::
Exception
makeTimeoutException
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment