-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy patherrors.go
116 lines (92 loc) · 2.35 KB
/
errors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// SPDX-FileCopyrightText: 2021 Henry Bubert
//
// SPDX-License-Identifier: MIT
package muxrpc
import (
"encoding/json"
"errors"
stderr "errors"
"fmt"
"io"
"net"
"os"
"syscall"
)
// ErrSessionTerminated is returned once Terminate() was called or the connection dies
var ErrSessionTerminated = errors.New("muxrpc: session terminated")
var errSinkClosed = stderr.New("muxrpc: pour to closed sink")
type ErrNoSuchMethod struct {
Method Method
}
func (e ErrNoSuchMethod) Error() string {
return fmt.Sprintf("muxrpc: no such command: %s", e.Method)
}
// CallError is returned when a call fails
type CallError struct {
Name string `json:"name"`
Message string `json:"message"`
Stack string `json:"stack"`
}
func (e CallError) Error() string {
return fmt.Sprintf("muxrpc CallError: %s - %s", e.Name, e.Message)
}
func parseError(data []byte) (*CallError, error) {
var e CallError
err := json.Unmarshal(data, &e)
if err != nil {
return nil, fmt.Errorf("muxrpc: failed to unmarshal error packet: %w", err)
}
// There are also TypeErrors and numerous other things we might get from this..
// if e.Name != "Error" {
// return nil, fmt.Errorf(`name is not "Error" but %q`, e.Name)
// }
return &e, nil
}
type ErrWrongStreamType struct{ ct CallType }
func (wst ErrWrongStreamType) Error() string {
return fmt.Sprintf("muxrpc: wrong stream type: %s", wst.ct)
}
// IsSinkClosed should be moved to luigi to gether with the error
func IsSinkClosed(err error) bool {
if err == nil {
return false
}
if err == errSinkClosed {
return true
}
if err == ErrSessionTerminated {
return true
}
if isAlreadyClosed(err) {
return true
}
var ce *CallError
if errors.As(err, &ce) && ce.Message == "unexpected end of parent stream" {
return true
}
return false
}
func isAlreadyClosed(err error) bool {
if err == nil {
return false
}
if stderr.Is(err, io.EOF) || stderr.Is(err, os.ErrClosed) || stderr.Is(err, io.ErrClosedPipe) {
return true
}
if sysErr, ok := (err).(*os.PathError); ok {
if sysErr.Err == os.ErrClosed {
// fmt.Printf("debug: found syscall err: %T) %s\n", err, err)
return true
}
}
if opErr, ok := err.(*net.OpError); ok {
if syscallErr, ok := opErr.Err.(*os.SyscallError); ok {
if errNo, ok := syscallErr.Err.(syscall.Errno); ok {
if errNo == syscall.EPIPE {
return true
}
}
}
}
return false
}