Commit 60bf8f54 authored by Sietse Ringers's avatar Sietse Ringers
Browse files

Catch panics in some goroutines

parent c6be2dac
......@@ -605,6 +605,14 @@ func (cm *CredentialManager) unenrolledKeyshareServers() []SchemeManagerIdentifi
// KeyshareEnroll attempts to enroll at the keyshare server of the specified scheme manager.
func (cm *CredentialManager) KeyshareEnroll(manager SchemeManagerIdentifier, email, pin string) {
go func() {
defer func() {
handlePanic(func(err *SessionError) {
if cm.handler != nil {
cm.handler.EnrollmentError(manager, err)
}
})
}()
err := cm.keyshareEnrollWorker(manager, email, pin)
cm.UnenrolledKeyshareServers = cm.unenrolledKeyshareServers()
if err != nil {
......@@ -613,6 +621,7 @@ func (cm *CredentialManager) KeyshareEnroll(manager SchemeManagerIdentifier, ema
cm.handler.EnrollmentSuccess(manager)
}
}()
}
func (cm *CredentialManager) keyshareEnrollWorker(managerID SchemeManagerIdentifier, email, pin string) error {
......
......@@ -105,6 +105,8 @@ const (
ErrorConfigurationStoreDownload = ErrorType("configurationStoreDownload")
// IRMA requests refers to unknown scheme manager
ErrorUnknownSchemeManager = ErrorType("unknownSchemeManager")
// Recovered panic
ErrorPanic = ErrorType("panic")
)
func (e *SessionError) Error() string {
......
......@@ -133,6 +133,25 @@ func (cm *CredentialManager) NewSession(qr *Qr, handler Handler) {
return
}
func handlePanic(callback func(*SessionError)) {
if e := recover(); e != nil {
var info string
switch x := e.(type) {
case string:
info = x
case error:
info = x.Error()
case fmt.Stringer:
info = x.String()
default: // nop
}
fmt.Printf("Recovered from panic: '%v'\n%s\n", e, info)
if callback != nil {
callback(&SessionError{ErrorType: ErrorPanic, Info: info})
}
}
}
func (session *session) fail(err *SessionError) {
session.transport.Delete()
err.Err = errors.Wrap(err.Err, 0)
......@@ -153,6 +172,14 @@ func (session *session) cancel() {
// start retrieves the first message in the IRMA protocol, checks if we can perform
// the request, and informs the user of the outcome.
func (session *session) start() {
defer func() {
handlePanic(func(err *SessionError) {
if session.Handler != nil {
session.Handler.Failure(session.Action, err)
}
})
}()
session.Handler.StatusUpdate(session.Action, StatusCommunicating)
if session.Action == ActionSchemeManager {
......@@ -253,6 +280,14 @@ func (session *session) start() {
}
func (session *session) do(proceed bool) {
defer func() {
handlePanic(func(err *SessionError) {
if session.Handler != nil {
session.Handler.Failure(session.Action, err)
}
})
}()
if !proceed {
session.cancel()
return
......
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