Skip to content
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

Propagate GoAway errors #34

Merged
merged 2 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions src/hyperx/clientserver.nim
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ type
peerWindowUpdateSig: SignalAsync
windowPending, windowProcessed: int
windowUpdateSig: SignalAsync
error*: ref HyperxError # XXX HyperxConnError
error*: ref HyperxConnError
when defined(hyperxStats):
frmsSent: int
frmsSentTyp: array[10, int]
Expand Down Expand Up @@ -304,15 +304,15 @@ func hpackEncode*(
client: ClientContext,
payload: var seq[byte], # XXX var string
name, value: openArray[char]
) {.raises: [HyperxError].} =
) {.raises: [HyperxConnError].} =
## headers must be added synchronously, no await in between,
## or else a table resize could occur in the meantime
try:
discard hencode(name, value, client.headersEnc, payload, huffman = false)
except HpackError as err:
debugInfo err.getStackTrace()
debugInfo err.msg
raise newException(HyperxError, err.msg)
raise newConnError(err.msg)

proc sendNaked(client: ClientContext, frm: Frame) {.async.} =
debugInfo "===SENT==="
Expand All @@ -334,7 +334,14 @@ proc sendNaked(client: ClientContext, frm: Frame) {.async.} =
proc send(client: ClientContext, frm: Frame) {.async.} =
try:
await client.sendNaked(frm)
except HyperxConnError, OsError, SslError:
except HyperxConnError as err:
if client.isConnected:
debugInfo err.getStackTrace()
debugInfo err.msg
client.error = newError err
client.close()
raise err
except OsError, SslError:
let err = getCurrentException()
if client.isConnected:
debugInfo err.getStackTrace()
Expand Down Expand Up @@ -520,7 +527,7 @@ proc recvTask(client: ClientContext) {.async.} =
debugInfo err.getStackTrace()
debugInfo err.msg
if client.isConnected:
client.error = newConnError(err.code)
client.error = newError err
await client.sendSilently newGoAwayFrame(
client.maxPeerStreamIdSeen, err.code
)
Expand Down Expand Up @@ -614,7 +621,7 @@ proc consumeMainStream(client: ClientContext, frm: Frame) {.async.} =
strm.pingSig.trigger()
of frmtGoAway:
client.isGracefulShutdown = true
client.error ?= newConnError frm.errCode()
client.error ?= newConnError(frm.errCode(), hyxRemoteErr)
# streams are never created by ctServer,
# so there are no streams to close
if client.typ == ctClient:
Expand Down Expand Up @@ -709,7 +716,7 @@ proc recvDispatcher(client: ClientContext) {.async.} =
debugInfo err.getStackTrace()
debugInfo err.msg
if client.isConnected:
client.error = newConnError(err.code)
client.error = newError err
await client.sendSilently newGoAwayFrame(
client.maxPeerStreamIdSeen, err.code
)
Expand All @@ -718,12 +725,6 @@ proc recvDispatcher(client: ClientContext) {.async.} =
debugInfo getCurrentException().getStackTrace()
debugInfo getCurrentException().msg
doAssert false
except HyperxError as err: # XXX remove
if client.isConnected:
debugInfo err.getStackTrace()
debugInfo err.msg
client.error = err # XXX fix
raise err
except CatchableError as err:
debugInfo err.getStackTrace()
debugInfo err.msg
Expand All @@ -748,11 +749,11 @@ proc windowUpdateTask(client: ClientContext) {.async.} =
await client.windowUpdateTaskNaked()
except QueueClosedError:
doAssert not client.isConnected
except HyperxError as err:
except HyperxConnError as err:
if client.isConnected:
debugInfo err.getStackTrace()
debugInfo err.msg
client.error = err
client.error = newError err
raise err
except CatchableError as err:
debugInfo err.getStackTrace()
Expand Down Expand Up @@ -1029,7 +1030,7 @@ proc recvTask(strm: ClientStream) {.async.} =
debugInfo err.msg
connErr = true
if client.isConnected:
client.error = newConnError(err.code)
client.error = newError err
await client.sendSilently newGoAwayFrame(
client.maxPeerStreamIdSeen, err.code
)
Expand Down
31 changes: 18 additions & 13 deletions src/hyperx/errors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -51,35 +51,40 @@ type
HyperxErrTyp* = enum
hyxLocalErr, hyxRemoteErr
HyperxError* = object of CatchableError
#typ*: HyperxErrTyp
#code*: HyperxErrCode
HyperxConnError* = object of HyperxError
code*: HyperxErrCode
HyperxStrmError* = object of HyperxError
typ*: HyperxErrTyp
code*: HyperxErrCode
HyperxConnError* = object of HyperxError
HyperxStrmError* = object of HyperxError
ConnClosedError* = object of HyperxConnError
GracefulShutdownError* = HyperxConnError
QueueClosedError* = object of HyperxError

func newConnClosedError*: ref ConnClosedError {.raises: [].} =
result = (ref ConnClosedError)(code: hyxUnknown, msg: "Connection Closed")
result = (ref ConnClosedError)(typ: hyxLocalErr, code: hyxInternalError, msg: "Connection Closed")

func newConnError*(msg: string): ref HyperxConnError {.raises: [].} =
result = (ref HyperxConnError)(code: hyxInternalError, msg: msg)
result = (ref HyperxConnError)(typ: hyxLocalErr, code: hyxInternalError, msg: msg)

func newConnError*(errCode: HyperxErrCode): ref HyperxConnError {.raises: [].} =
result = (ref HyperxConnError)(code: errCode, msg: "Connection Error: " & $errCode)
func newConnError*(
errCode: HyperxErrCode, typ = hyxLocalErr
): ref HyperxConnError {.raises: [].} =
result = (ref HyperxConnError)(
typ: typ, code: errCode, msg: "Connection Error: " & $errCode
)

func newConnError*(errCode: uint32): ref HyperxConnError {.raises: [].} =
func newConnError*(
errCode: uint32, typ = hyxLocalErr
): ref HyperxConnError {.raises: [].} =
result = (ref HyperxConnError)(
typ: typ,
code: errCode.toErrorCode,
msg: "Connection Error: " & $errCode.toErrorCode
)

# XXX fix
func newError*(err: ref HyperxError): ref HyperxConnError {.raises: [].} =
result = (ref HyperxConnError)(code: hyxUnknown, msg: err.msg)
func newError*(err: ref HyperxConnError): ref HyperxConnError {.raises: [].} =
result = (ref HyperxConnError)(
typ: err.typ, code: err.code, msg: err.msg
)

func newStrmError*(
errCode: HyperxErrCode, typ = hyxLocalErr
Expand Down
Loading