lint: ensure errors are at least logged (errcheck)

Signed-off-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
Moritz Poldrack 2022-07-29 22:31:54 +02:00 committed by Robin Jarry
parent a8d631177f
commit 5ca6022d00
33 changed files with 301 additions and 103 deletions

15
aerc.go
View file

@ -164,7 +164,10 @@ func main() {
deferLoop := make(chan struct{}) deferLoop := make(chan struct{})
c := crypto.New(conf.General.PgpProvider) c := crypto.New(conf.General.PgpProvider)
c.Init() err = c.Init()
if err != nil {
logging.Warnf("failed to initialise crypto interface: %v", err)
}
defer c.Close() defer c.Close()
aerc = widgets.NewAerc(conf, c, func(cmd []string) error { aerc = widgets.NewAerc(conf, c, func(cmd []string) error {
@ -205,7 +208,10 @@ func main() {
err := lib.ConnectAndExec(arg) err := lib.ConnectAndExec(arg)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "Failed to communicate to aerc: %v\n", err) fmt.Fprintf(os.Stderr, "Failed to communicate to aerc: %v\n", err)
aerc.CloseBackends() err = aerc.CloseBackends()
if err != nil {
logging.Warnf("failed to close backends: %v", err)
}
return return
} }
} }
@ -223,5 +229,8 @@ func main() {
time.Sleep(16 * time.Millisecond) time.Sleep(16 * time.Millisecond)
} }
} }
aerc.CloseBackends() err = aerc.CloseBackends()
if err != nil {
logging.Warnf("failed to close backends: %v", err)
}
} }

View file

@ -96,7 +96,10 @@ func (ExportMbox) Execute(aerc *widgets.Aerc, args []string) error {
done <- false done <- false
case *types.FullMessage: case *types.FullMessage:
mu.Lock() mu.Lock()
mboxer.Write(file, msg.Content.Reader, "", t) err := mboxer.Write(file, msg.Content.Reader, "", t)
if err != nil {
logging.Warnf("failed to write mbox: %v", err)
}
for i, uid := range uids { for i, uid := range uids {
if uid == msg.Content.Uid { if uid == msg.Content.Uid {
uids = append(uids[:i], uids[i+1:]...) uids = append(uids[:i], uids[i+1:]...)

View file

@ -133,14 +133,20 @@ func (forward) Execute(aerc *widgets.Aerc, args []string) error {
store.FetchFull([]uint32{msg.Uid}, func(fm *types.FullMessage) { store.FetchFull([]uint32{msg.Uid}, func(fm *types.FullMessage) {
tmpFile, err := os.Create(tmpFileName) tmpFile, err := os.Create(tmpFileName)
if err != nil { if err != nil {
println(err) logging.Warnf("failed to create temporary attachment: %v", err)
// TODO: Do something with the error _, err = addTab()
addTab() if err != nil {
logging.Warnf("failed to add tab: %v", err)
}
return return
} }
defer tmpFile.Close() defer tmpFile.Close()
io.Copy(tmpFile, fm.Content.Reader) _, err = io.Copy(tmpFile, fm.Content.Reader)
if err != nil {
logging.Warnf("failed to write to tmpfile: %w", err)
return
}
composer, err := addTab() composer, err := addTab()
if err != nil { if err != nil {
return return

View file

@ -8,6 +8,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/lib/calendar" "git.sr.ht/~rjarry/aerc/lib/calendar"
"git.sr.ht/~rjarry/aerc/lib/format" "git.sr.ht/~rjarry/aerc/lib/format"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/widgets" "git.sr.ht/~rjarry/aerc/widgets"
"github.com/emersion/go-message/mail" "github.com/emersion/go-message/mail"
@ -153,7 +154,10 @@ func (invite) Execute(aerc *widgets.Aerc, args []string) error {
} }
composer.SetContents(cr.PlainText) composer.SetContents(cr.PlainText)
composer.AppendPart(cr.MimeType, cr.Params, cr.CalendarText) err = composer.AppendPart(cr.MimeType, cr.Params, cr.CalendarText)
if err != nil {
return fmt.Errorf("failed to write invitation: %w", err)
}
composer.FocusTerminal() composer.FocusTerminal()
tab := aerc.NewTab(composer, subject) tab := aerc.NewTab(composer, subject)
@ -180,7 +184,10 @@ func (invite) Execute(aerc *widgets.Aerc, args []string) error {
aerc.PushError(err.Error()) aerc.PushError(err.Error())
return return
} else { } else {
addTab(cr) err := addTab(cr)
if err != nil {
logging.Warnf("failed to add tab: %v", err)
}
} }
}) })
return nil return nil

View file

@ -96,7 +96,10 @@ func (Pipe) Execute(aerc *widgets.Aerc, args []string) error {
defer logging.PanicHandler() defer logging.PanicHandler()
defer pipe.Close() defer pipe.Close()
io.Copy(pipe, reader) _, err := io.Copy(pipe, reader)
if err != nil {
logging.Errorf("failed to send data to pipe: %w", err)
}
}() }()
err = ecmd.Run() err = ecmd.Run()
if err != nil { if err != nil {
@ -224,10 +227,14 @@ func newMessagesReader(messages []*types.FullMessage, useMbox bool) io.Reader {
go func() { go func() {
defer pw.Close() defer pw.Close()
for _, msg := range messages { for _, msg := range messages {
var err error
if useMbox { if useMbox {
mboxer.Write(pw, msg.Content.Reader, "", time.Now()) err = mboxer.Write(pw, msg.Content.Reader, "", time.Now())
} else { } else {
io.Copy(pw, msg.Content.Reader) _, err = io.Copy(pw, msg.Content.Reader)
}
if err != nil {
logging.Warnf("failed to write data: %v", err)
} }
} }
}() }()

View file

@ -182,7 +182,10 @@ func (Recall) Execute(aerc *widgets.Aerc, args []string) error {
composer.SetEncrypt(md.IsEncrypted) composer.SetEncrypt(md.IsEncrypted)
} }
if md.IsSigned { if md.IsSigned {
composer.SetSign(md.IsSigned) err = composer.SetSign(md.IsSigned)
if err != nil {
logging.Warnf("failed to set signed state: %v", err)
}
} }
} }
addTab() addTab()

View file

@ -12,6 +12,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/lib/format" "git.sr.ht/~rjarry/aerc/lib/format"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/widgets" "git.sr.ht/~rjarry/aerc/widgets"
"github.com/emersion/go-message/mail" "github.com/emersion/go-message/mail"
@ -224,9 +225,15 @@ func (reply) Execute(aerc *widgets.Aerc, args []string) error {
store.FetchBodyPart(msg.Uid, part, func(reader io.Reader) { store.FetchBodyPart(msg.Uid, part, func(reader io.Reader) {
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
buf.ReadFrom(reader) _, err := buf.ReadFrom(reader)
if err != nil {
logging.Warnf("failed to fetch bodypart: %v", err)
}
original.Text = buf.String() original.Text = buf.String()
addTab() err = addTab()
if err != nil {
logging.Warnf("failed to add tab: %v", err)
}
}) })
return nil return nil
} else { } else {

View file

@ -95,7 +95,7 @@ func (c *Completer) completeAddress(s string) ([]string, string, error) {
// programs will do to signal no matches. We don't want to spam the user with // programs will do to signal no matches. We don't want to spam the user with
// spurious error messages, so we'll ignore any errors that arise at this // spurious error messages, so we'll ignore any errors that arise at this
// point. // point.
defer cmd.Wait() defer cmd.Wait() //nolint:errcheck // see above
completions, err := readCompletions(stdout) completions, err := readCompletions(stdout)
if err != nil { if err != nil {

View file

@ -1042,7 +1042,10 @@ func (config AercConfig) mergeContextualUi(baseUi UIConfig,
continue continue
} }
mergo.Merge(&baseUi, contextualUi.UiConfig, mergo.WithOverride) err := mergo.Merge(&baseUi, contextualUi.UiConfig, mergo.WithOverride)
if err != nil {
logging.Warnf("merge ui failed: %v", err)
}
if contextualUi.UiConfig.StyleSetName != "" { if contextualUi.UiConfig.StyleSetName != "" {
baseUi.style = contextualUi.UiConfig.style baseUi.style = contextualUi.UiConfig.style
} }

View file

@ -119,7 +119,10 @@ type calendar struct {
func parse(reader io.Reader) (*calendar, error) { func parse(reader io.Reader) (*calendar, error) {
// fix capitalized mailto for parsing of ics file // fix capitalized mailto for parsing of ics file
var sb strings.Builder var sb strings.Builder
io.Copy(&sb, reader) _, err := io.Copy(&sb, reader)
if err != nil {
return nil, fmt.Errorf("failed to copy calendar data: %w", err)
}
re := regexp.MustCompile("MAILTO:(.+@)") re := regexp.MustCompile("MAILTO:(.+@)")
str := re.ReplaceAllString(sb.String(), "mailto:${1}") str := re.ReplaceAllString(sb.String(), "mailto:${1}")

View file

@ -25,15 +25,18 @@ func Encrypt(r io.Reader, to []string, from string) ([]byte, error) {
args = append(args, "--encrypt", "-") args = append(args, "--encrypt", "-")
g := newGpg(r, args) g := newGpg(r, args)
g.cmd.Run() err := g.cmd.Run()
if err != nil {
return nil, fmt.Errorf("gpg: failed to run encryption: %w", err)
}
outRdr := bytes.NewReader(g.stdout.Bytes()) outRdr := bytes.NewReader(g.stdout.Bytes())
var md models.MessageDetails var md models.MessageDetails
err := parse(outRdr, &md) err = parse(outRdr, &md)
if err != nil { if err != nil {
return nil, fmt.Errorf("gpg: failure to encrypt: %v. check public key(s)", err) return nil, fmt.Errorf("gpg: failure to encrypt: %v. check public key(s)", err)
} }
var buf bytes.Buffer var buf bytes.Buffer
io.Copy(&buf, md.Body) _, _ = io.Copy(&buf, md.Body)
return buf.Bytes(), nil return buf.Bytes(), nil
} }

View file

@ -63,7 +63,11 @@ func getIdentity(key uint64) string {
var outbuf strings.Builder var outbuf strings.Builder
cmd.Stdout = &outbuf cmd.Stdout = &outbuf
cmd.Run() err := cmd.Run()
if err != nil {
logging.Errorf("gpg: failed to get identity: %v", err)
return ""
}
out := strings.Split(outbuf.String(), "\n") out := strings.Split(outbuf.String(), "\n")
for _, line := range out { for _, line := range out {
if strings.HasPrefix(line, "uid") { if strings.HasPrefix(line, "uid") {
@ -85,7 +89,11 @@ func getKeyId(s string, private bool) string {
var outbuf strings.Builder var outbuf strings.Builder
cmd.Stdout = &outbuf cmd.Stdout = &outbuf
cmd.Run() err := cmd.Run()
if err != nil {
logging.Errorf("gpg: failed to get key ID: %v", err)
return ""
}
out := strings.Split(outbuf.String(), "\n") out := strings.Split(outbuf.String(), "\n")
for _, line := range out { for _, line := range out {
if strings.HasPrefix(line, "fpr") { if strings.HasPrefix(line, "fpr") {

View file

@ -36,7 +36,10 @@ func ExportPublicKey(k string) (io.Reader, error) {
var stderr strings.Builder var stderr strings.Builder
cmd.Stdout = &outbuf cmd.Stdout = &outbuf
cmd.Stderr = &stderr cmd.Stderr = &stderr
cmd.Run() err := cmd.Run()
if err != nil {
return nil, fmt.Errorf("gpg: export failed: %w", err)
}
if strings.Contains(stderr.String(), "gpg") { if strings.Contains(stderr.String(), "gpg") {
return nil, fmt.Errorf("gpg: error exporting key") return nil, fmt.Errorf("gpg: error exporting key")
} }

View file

@ -17,15 +17,18 @@ func Sign(r io.Reader, from string) ([]byte, string, error) {
} }
g := newGpg(r, args) g := newGpg(r, args)
g.cmd.Run() err := g.cmd.Run()
if err != nil {
return nil, "", fmt.Errorf("failed to run signing: %w", err)
}
outRdr := bytes.NewReader(g.stdout.Bytes()) outRdr := bytes.NewReader(g.stdout.Bytes())
var md models.MessageDetails var md models.MessageDetails
err := parse(outRdr, &md) err = parse(outRdr, &md)
if err != nil { if err != nil {
return nil, "", fmt.Errorf("failed to parse messagedetails: %v", err) return nil, "", fmt.Errorf("failed to parse messagedetails: %v", err)
} }
var buf bytes.Buffer var buf bytes.Buffer
io.Copy(&buf, md.Body) _, _ = io.Copy(&buf, md.Body)
return buf.Bytes(), md.Micalg, nil return buf.Bytes(), md.Micalg, nil
} }

View file

@ -2,6 +2,7 @@ package gpgbin
import ( import (
"bytes" "bytes"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
@ -19,7 +20,7 @@ func Verify(m io.Reader, s io.Reader) (*models.MessageDetails, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
io.Copy(sig, s) _, _ = io.Copy(sig, s)
sig.Close() sig.Close()
defer os.Remove(sig.Name()) defer os.Remove(sig.Name())
args = append(args, sig.Name(), "-") args = append(args, sig.Name(), "-")
@ -29,11 +30,17 @@ func Verify(m io.Reader, s io.Reader) (*models.MessageDetails, error) {
return nil, err return nil, err
} }
g := newGpg(bytes.NewReader(orig), args) g := newGpg(bytes.NewReader(orig), args)
g.cmd.Run() err = g.cmd.Run()
if err != nil {
return nil, fmt.Errorf("gpg: failed to run verification: %w", err)
}
out := bytes.NewReader(g.stdout.Bytes()) out := bytes.NewReader(g.stdout.Bytes())
md := new(models.MessageDetails) md := new(models.MessageDetails)
parse(out, md) err = parse(out, md)
if err != nil {
return nil, fmt.Errorf("gpg: failed to parse result: %w", err)
}
md.Body = bytes.NewReader(orig) md.Body = bytes.NewReader(orig)

View file

@ -38,7 +38,7 @@ func NewReader(h textproto.Header, body io.Reader) (*Reader, error) {
} }
var headerBuf bytes.Buffer var headerBuf bytes.Buffer
textproto.WriteHeader(&headerBuf, h) _ = textproto.WriteHeader(&headerBuf, h)
return &Reader{ return &Reader{
Header: h, Header: h,
@ -123,7 +123,7 @@ func newEncryptedReader(h textproto.Header, mr *textproto.MultipartReader) (*Rea
} }
var headerBuf bytes.Buffer var headerBuf bytes.Buffer
textproto.WriteHeader(&headerBuf, cleartextHeader) _ = textproto.WriteHeader(&headerBuf, cleartextHeader)
md.Body = io.MultiReader(&headerBuf, cleartext) md.Body = io.MultiReader(&headerBuf, cleartext)
return &Reader{ return &Reader{
@ -139,11 +139,11 @@ func newSignedReader(h textproto.Header, mr *textproto.MultipartReader, micalg s
return nil, fmt.Errorf("gpgmail: failed to read signed part in multipart/signed message: %v", err) return nil, fmt.Errorf("gpgmail: failed to read signed part in multipart/signed message: %v", err)
} }
var headerBuf bytes.Buffer var headerBuf bytes.Buffer
textproto.WriteHeader(&headerBuf, p.Header) _ = textproto.WriteHeader(&headerBuf, p.Header)
var msg bytes.Buffer var msg bytes.Buffer
headerRdr := bytes.NewReader(headerBuf.Bytes()) headerRdr := bytes.NewReader(headerBuf.Bytes())
fullMsg := io.MultiReader(headerRdr, p) fullMsg := io.MultiReader(headerRdr, p)
io.Copy(&msg, fullMsg) _, _ = io.Copy(&msg, fullMsg)
sig, err := mr.NextPart() sig, err := mr.NextPart()
if err != nil { if err != nil {

View file

@ -30,7 +30,10 @@ func (es *EncrypterSigner) Close() (err error) {
if err != nil { if err != nil {
return err return err
} }
es.encryptedWriter.Write(enc) _, err = es.encryptedWriter.Write(enc)
if err != nil {
return fmt.Errorf("gpg: failed to write encrypted writer: %w", err)
}
return nil return nil
} }
@ -65,8 +68,8 @@ func (s *Signer) Close() (err error) {
} }
boundary := s.mw.Boundary() boundary := s.mw.Boundary()
fmt.Fprintf(s.w, "--%s\r\n", boundary) fmt.Fprintf(s.w, "--%s\r\n", boundary)
s.w.Write(s.signedMsg.Bytes()) _, _ = s.w.Write(s.signedMsg.Bytes())
s.w.Write([]byte("\r\n")) _, _ = s.w.Write([]byte("\r\n"))
var signedHeader textproto.Header var signedHeader textproto.Header
signedHeader.Set("Content-Type", "application/pgp-signature; name=\"signature.asc\"") signedHeader.Set("Content-Type", "application/pgp-signature; name=\"signature.asc\"")
@ -100,7 +103,10 @@ func Encrypt(w io.Writer, h textproto.Header, rcpts []string, from string) (io.W
mw := textproto.NewMultipartWriter(w) mw := textproto.NewMultipartWriter(w)
if forceBoundary != "" { if forceBoundary != "" {
mw.SetBoundary(forceBoundary) err := mw.SetBoundary(forceBoundary)
if err != nil {
return nil, fmt.Errorf("gpg: failed to set boundary: %w", err)
}
} }
params := map[string]string{ params := map[string]string{
@ -154,7 +160,10 @@ func Sign(w io.Writer, h textproto.Header, from string) (io.WriteCloser, error)
mw := textproto.NewMultipartWriter(w) mw := textproto.NewMultipartWriter(w)
if forceBoundary != "" { if forceBoundary != "" {
mw.SetBoundary(forceBoundary) err := mw.SetBoundary(forceBoundary)
if err != nil {
return nil, fmt.Errorf("gpg: failed to set boundary: %w", err)
}
} }
var msg bytes.Buffer var msg bytes.Buffer

View file

@ -31,7 +31,10 @@ var (
func (m *Mail) Init() error { func (m *Mail) Init() error {
logging.Infof("Initializing PGP keyring") logging.Infof("Initializing PGP keyring")
os.MkdirAll(path.Join(xdg.DataHome(), "aerc"), 0o700) err := os.MkdirAll(path.Join(xdg.DataHome(), "aerc"), 0o700)
if err != nil {
return fmt.Errorf("failed to create data directory: %v", err)
}
lockpath := path.Join(xdg.DataHome(), "aerc", "keyring.lock") lockpath := path.Join(xdg.DataHome(), "aerc", "keyring.lock")
lockfile, err := os.OpenFile(lockpath, os.O_CREATE|os.O_EXCL, 0o600) lockfile, err := os.OpenFile(lockpath, os.O_CREATE|os.O_EXCL, 0o600)
@ -294,7 +297,7 @@ func (m *Mail) ExportKey(k string) (io.Reader, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("pgp: error exporting key: %v", err) return nil, fmt.Errorf("pgp: error exporting key: %v", err)
} }
w.Write(pks.Bytes()) _, err = w.Write(pks.Bytes())
if err != nil { if err != nil {
return nil, fmt.Errorf("pgp: error exporting key: %v", err) return nil, fmt.Errorf("pgp: error exporting key: %v", err)
} }

View file

@ -225,7 +225,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
newMap := make(map[uint32]*models.MessageInfo) newMap := make(map[uint32]*models.MessageInfo)
for i := len(msg.Threads) - 1; i >= 0; i-- { for i := len(msg.Threads) - 1; i >= 0; i-- {
msg.Threads[i].Walk(func(t *types.Thread, level int, currentErr error) error { _ = msg.Threads[i].Walk(func(t *types.Thread, level int, currentErr error) error {
uid := t.Uid uid := t.Uid
uids = append([]uint32{uid}, uids...) uids = append([]uint32{uid}, uids...)
if msg, ok := store.Messages[uid]; ok { if msg, ok := store.Messages[uid]; ok {
@ -316,7 +316,7 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
store.results = newResults store.results = newResults
for _, thread := range store.Threads() { for _, thread := range store.Threads() {
thread.Walk(func(t *types.Thread, _ int, _ error) error { _ = thread.Walk(func(t *types.Thread, _ int, _ error) error {
if _, deleted := toDelete[t.Uid]; deleted { if _, deleted := toDelete[t.Uid]; deleted {
t.Deleted = true t.Deleted = true
} }

View file

@ -64,40 +64,56 @@ func (as *AercServer) handleClient(conn net.Conn) {
clientId := atomic.AddInt64(&lastId, 1) clientId := atomic.AddInt64(&lastId, 1)
logging.Debugf("unix:%d accepted connection", clientId) logging.Debugf("unix:%d accepted connection", clientId)
scanner := bufio.NewScanner(conn) scanner := bufio.NewScanner(conn)
conn.SetDeadline(time.Now().Add(1 * time.Minute)) err := conn.SetDeadline(time.Now().Add(1 * time.Minute))
if err != nil {
logging.Errorf("failed to set deadline: %v", err)
}
for scanner.Scan() { for scanner.Scan() {
conn.SetDeadline(time.Now().Add(1 * time.Minute)) err = conn.SetDeadline(time.Now().Add(1 * time.Minute))
if err != nil {
logging.Errorf("failed to update deadline: %v", err)
}
msg := scanner.Text() msg := scanner.Text()
logging.Debugf("unix:%d got message %s", clientId, msg) logging.Debugf("unix:%d got message %s", clientId, msg)
if !strings.ContainsRune(msg, ':') { if !strings.ContainsRune(msg, ':') {
conn.Write([]byte("error: invalid command\n")) _, innererr := conn.Write([]byte("error: invalid command\n"))
if innererr != nil {
logging.Errorf("failed to write error message: %v", innererr)
}
continue continue
} }
prefix := msg[:strings.IndexRune(msg, ':')] prefix := msg[:strings.IndexRune(msg, ':')]
var err error
switch prefix { switch prefix {
case "mailto": case "mailto":
mailto, err := url.Parse(msg) mailto, err := url.Parse(msg)
if err != nil { if err != nil {
conn.Write([]byte(fmt.Sprintf("error: %v\n", err))) _, innererr := conn.Write([]byte(fmt.Sprintf("error: %v\n", err)))
if innererr != nil {
logging.Errorf("failed to write error message: %v", innererr)
}
break break
} }
if as.OnMailto != nil { if as.OnMailto != nil {
err = as.OnMailto(mailto) err = as.OnMailto(mailto)
} if err != nil {
if err != nil { logging.Errorf("mailto failed: %v", err)
conn.Write([]byte(fmt.Sprintf("result: %v\n", err))) }
} else {
conn.Write([]byte("result: success\n"))
} }
case "mbox": case "mbox":
var err error
if as.OnMbox != nil { if as.OnMbox != nil {
err = as.OnMbox(msg) err = as.OnMbox(msg)
} }
}
if err != nil {
_, err = conn.Write([]byte(fmt.Sprintf("result: %v\n", err)))
if err != nil { if err != nil {
conn.Write([]byte(fmt.Sprintf("result: %v\n", err))) logging.Errorf("failed to send error: %v")
} else { }
conn.Write([]byte("result: success\n")) } else {
_, err = conn.Write([]byte("result: success\n"))
if err != nil {
logging.Errorf("failed to send successmessage: %v")
} }
} }
} }
@ -110,7 +126,10 @@ func ConnectAndExec(msg string) error {
if err != nil { if err != nil {
return err return err
} }
conn.Write([]byte(msg + "\n")) _, err = conn.Write([]byte(msg + "\n"))
if err != nil {
return fmt.Errorf("failed to send message: %w", err)
}
scanner := bufio.NewScanner(conn) scanner := bufio.NewScanner(conn)
if !scanner.Scan() { if !scanner.Scan() {
return errors.New("No response from server") return errors.New("No response from server")

View file

@ -155,7 +155,7 @@ func (builder *ThreadBuilder) sortThreads(threads []*types.Thread, orderedUids [
func (builder *ThreadBuilder) RebuildUids(threads []*types.Thread) { func (builder *ThreadBuilder) RebuildUids(threads []*types.Thread) {
uids := make([]uint32, 0, len(threads)) uids := make([]uint32, 0, len(threads))
for i := len(threads) - 1; i >= 0; i-- { for i := len(threads) - 1; i >= 0; i-- {
threads[i].Walk(func(t *types.Thread, level int, currentErr error) error { _ = threads[i].Walk(func(t *types.Thread, level int, currentErr error) error {
uids = append(uids, t.Uid) uids = append(uids, t.Uid)
return nil return nil
}) })

View file

@ -36,7 +36,7 @@ func Debugf(message string, args ...interface{}) {
if len(args) > 0 { if len(args) > 0 {
message = fmt.Sprintf(message, args...) message = fmt.Sprintf(message, args...)
} }
dbg.Output(2, message) dbg.Output(2, message) //nolint:errcheck // we can't do anything with what we log
} }
func Infof(message string, args ...interface{}) { func Infof(message string, args ...interface{}) {
@ -46,7 +46,7 @@ func Infof(message string, args ...interface{}) {
if len(args) > 0 { if len(args) > 0 {
message = fmt.Sprintf(message, args...) message = fmt.Sprintf(message, args...)
} }
info.Output(2, message) info.Output(2, message) //nolint:errcheck // we can't do anything with what we log
} }
func Warnf(message string, args ...interface{}) { func Warnf(message string, args ...interface{}) {
@ -56,7 +56,7 @@ func Warnf(message string, args ...interface{}) {
if len(args) > 0 { if len(args) > 0 {
message = fmt.Sprintf(message, args...) message = fmt.Sprintf(message, args...)
} }
warn.Output(2, message) warn.Output(2, message) //nolint:errcheck // we can't do anything with what we log
} }
func Errorf(message string, args ...interface{}) { func Errorf(message string, args ...interface{}) {
@ -66,5 +66,5 @@ func Errorf(message string, args ...interface{}) {
if len(args) > 0 { if len(args) > 0 {
message = fmt.Sprintf(message, args...) message = fmt.Sprintf(message, args...)
} }
err.Output(2, message) err.Output(2, message) //nolint:errcheck // we can't do anything with what we log
} }

View file

@ -42,7 +42,7 @@ func PanicHandler() {
fmt.Fprintln(panicLog, strings.Repeat("#", 80)) fmt.Fprintln(panicLog, strings.Repeat("#", 80))
fmt.Fprintf(outputs, "%s\n", panicMessage) fmt.Fprintf(outputs, "%s\n", panicMessage)
fmt.Fprintf(panicLog, "Error: %v\n\n", r) fmt.Fprintf(panicLog, "Error: %v\n\n", r)
panicLog.Write(debug.Stack()) panicLog.Write(debug.Stack()) //nolint:errcheck // we are already in a panic, so not much we can do here
fmt.Fprintf(os.Stderr, "\nThis error was also written to: %s\n", filename) fmt.Fprintf(os.Stderr, "\nThis error was also written to: %s\n", filename)
panic(r) panic(r)
} }

View file

@ -493,16 +493,17 @@ func (wizard *AccountWizard) finish(tutorial bool) {
return return
} }
sec, _ = file.NewSection(wizard.accountName.String()) sec, _ = file.NewSection(wizard.accountName.String())
sec.NewKey("source", wizard.imapUrl.String()) // these can't really fail
sec.NewKey("outgoing", wizard.smtpUrl.String()) sec.NewKey("source", wizard.imapUrl.String()) //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty
sec.NewKey("default", "INBOX") sec.NewKey("outgoing", wizard.smtpUrl.String()) //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty
sec.NewKey("default", "INBOX") //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty
if wizard.smtpMode == SMTP_STARTTLS { if wizard.smtpMode == SMTP_STARTTLS {
sec.NewKey("smtp-starttls", "yes") sec.NewKey("smtp-starttls", "yes") //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty
} }
sec.NewKey("from", fmt.Sprintf("%s <%s>", sec.NewKey("from", fmt.Sprintf("%s <%s>", //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty
wizard.fullName.String(), wizard.email.String())) wizard.fullName.String(), wizard.email.String()))
if wizard.copySent { if wizard.copySent {
sec.NewKey("copy-to", "Sent") sec.NewKey("copy-to", "Sent") //nolint:errcheck // can't fail. option shadowing is not enabled and the key is not empty
} }
if !wizard.temporary { if !wizard.temporary {

View file

@ -119,11 +119,15 @@ func NewComposer(aerc *Aerc, acct *AccountView, conf *config.AercConfig,
c.AddSignature() c.AddSignature()
c.updateGrid() c.updateGrid()
c.updateCrypto() err = c.updateCrypto()
if err != nil {
logging.Warnf("failed to update crypto: %v", err)
}
c.ShowTerminal() c.ShowTerminal()
if c.acctConfig.PgpAutoSign { if c.acctConfig.PgpAutoSign {
c.SetSign(true) err = c.SetSign(true)
logging.Warnf("failed to enable message signing: %v", err)
} }
if c.acctConfig.PgpOpportunisticEncrypt { if c.acctConfig.PgpOpportunisticEncrypt {
c.SetEncrypt(true) c.SetEncrypt(true)
@ -196,7 +200,10 @@ func (c *Composer) SetAttachKey(attach bool) error {
} }
} }
if found { if found {
c.DeleteAttachment(name) err := c.DeleteAttachment(name)
if err != nil {
return fmt.Errorf("failed to delete attachment '%s: %v", name, err)
}
} else { } else {
attach = !attach attach = !attach
} }
@ -264,7 +271,10 @@ func (c *Composer) Sign() bool {
func (c *Composer) SetEncrypt(encrypt bool) *Composer { func (c *Composer) SetEncrypt(encrypt bool) *Composer {
if !encrypt { if !encrypt {
c.encrypt = encrypt c.encrypt = encrypt
c.updateCrypto() err := c.updateCrypto()
if err != nil {
logging.Warnf("failed to update crypto: %v", err)
}
return c return c
} }
// Check on any attempt to encrypt, and any lost focus of "to", "cc", or // Check on any attempt to encrypt, and any lost focus of "to", "cc", or
@ -337,17 +347,38 @@ func (c *Composer) updateCrypto() error {
// Note: this does not reload the editor. You must call this before the first // Note: this does not reload the editor. You must call this before the first
// Draw() call. // Draw() call.
func (c *Composer) SetContents(reader io.Reader) *Composer { func (c *Composer) SetContents(reader io.Reader) *Composer {
c.email.Seek(0, io.SeekStart) _, err := c.email.Seek(0, io.SeekStart)
io.Copy(c.email, reader) if err != nil {
c.email.Sync() logging.Warnf("failed to seek beginning of mail: %v", err)
c.email.Seek(0, io.SeekStart) }
_, err = io.Copy(c.email, reader)
if err != nil {
logging.Warnf("failed to copy mail: %v", err)
}
err = c.email.Sync()
if err != nil {
logging.Warnf("failed to sync mail: %v", err)
}
_, err = c.email.Seek(0, io.SeekStart)
if err != nil {
logging.Warnf("failed to seek beginning of mail after sync: %v", err)
}
return c return c
} }
func (c *Composer) AppendContents(reader io.Reader) { func (c *Composer) AppendContents(reader io.Reader) {
c.email.Seek(0, io.SeekEnd) _, err := c.email.Seek(0, io.SeekEnd)
io.Copy(c.email, reader) if err != nil {
c.email.Sync() logging.Warnf("failed to seek beginning of mail: %v", err)
}
_, err = io.Copy(c.email, reader)
if err != nil {
logging.Warnf("failed to copy mail: %v", err)
}
err = c.email.Sync()
if err != nil {
logging.Warnf("failed to sync mail: %v", err)
}
} }
func (c *Composer) AppendPart(mimetype string, params map[string]string, body io.Reader) error { func (c *Composer) AppendPart(mimetype string, params map[string]string, body io.Reader) error {
@ -648,7 +679,10 @@ func (c *Composer) WriteMessage(header *mail.Header, writer io.Writer) error {
if err != nil { if err != nil {
return err return err
} }
io.Copy(writer, &buf) _, err = io.Copy(writer, &buf)
if err != nil {
return fmt.Errorf("failed to write message: %w", err)
}
return nil return nil
} else { } else {
@ -1242,6 +1276,9 @@ func (c *Composer) checkEncryptionKeys(_ string) bool {
// If callbacks were registered, encrypt will be set when user removes // If callbacks were registered, encrypt will be set when user removes
// recipients with missing keys // recipients with missing keys
c.encrypt = true c.encrypt = true
c.updateCrypto() err = c.updateCrypto()
if err != nil {
logging.Warnf("failed update crypto: %v", err)
}
return true return true
} }

View file

@ -8,6 +8,7 @@ import (
"git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/config"
"git.sr.ht/~rjarry/aerc/lib/ui" "git.sr.ht/~rjarry/aerc/lib/ui"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/worker/types" "git.sr.ht/~rjarry/aerc/worker/types"
"github.com/gdamore/tcell/v2" "github.com/gdamore/tcell/v2"
) )
@ -363,10 +364,13 @@ func (dt *DirectoryTree) buildTree() {
dt.list = make([]*types.Thread, 0) dt.list = make([]*types.Thread, 0)
for _, node := range threads { for _, node := range threads {
node.Walk(func(t *types.Thread, lvl int, err error) error { err := node.Walk(func(t *types.Thread, lvl int, err error) error {
dt.list = append(dt.list, t) dt.list = append(dt.list, t)
return nil return nil
}) })
if err != nil {
logging.Warnf("failed to walk tree: %v", err)
}
} }
} }
@ -420,12 +424,15 @@ func isVisible(node *types.Thread) bool {
} }
func getAnyUid(node *types.Thread) (uid uint32) { func getAnyUid(node *types.Thread) (uid uint32) {
node.Walk(func(t *types.Thread, l int, err error) error { err := node.Walk(func(t *types.Thread, l int, err error) error {
if t.FirstChild == nil { if t.FirstChild == nil {
uid = t.Uid uid = t.Uid
} }
return nil return nil
}) })
if err != nil {
logging.Warnf("failed to get uid: %v", err)
}
return return
} }

View file

@ -13,6 +13,7 @@ import (
"git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/lib"
"git.sr.ht/~rjarry/aerc/lib/format" "git.sr.ht/~rjarry/aerc/lib/format"
"git.sr.ht/~rjarry/aerc/lib/ui" "git.sr.ht/~rjarry/aerc/lib/ui"
"git.sr.ht/~rjarry/aerc/logging"
"git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/worker/types" "git.sr.ht/~rjarry/aerc/worker/types"
) )
@ -93,7 +94,7 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
for i := len(threads) - 1; i >= 0; i-- { for i := len(threads) - 1; i >= 0; i-- {
var lastSubject string var lastSubject string
threads[i].Walk(func(t *types.Thread, _ int, currentErr error) error { err := threads[i].Walk(func(t *types.Thread, _ int, currentErr error) error {
if currentErr != nil { if currentErr != nil {
return currentErr return currentErr
} }
@ -132,6 +133,9 @@ func (ml *MessageList) Draw(ctx *ui.Context) {
row++ row++
return nil return nil
}) })
if err != nil {
logging.Warnf("failed to walk threads: %v", err)
}
if row >= ctx.Height() { if row >= ctx.Height() {
break break
} }

View file

@ -645,7 +645,10 @@ func (pv *PartViewer) attemptCopy() {
pv.copySourceToSinkStripAnsi() pv.copySourceToSinkStripAnsi()
} else { } else {
// if it's binary we have to rely on the filter to be sane // if it's binary we have to rely on the filter to be sane
io.Copy(pv.sink, pv.source) _, err := io.Copy(pv.sink, pv.source)
if err != nil {
logging.Warnf("failed to copy: %w", err)
}
} }
pv.sink.Close() pv.sink.Close()
}() }()
@ -667,14 +670,23 @@ func (pv *PartViewer) writeMailHeaders() {
} }
field := fmt.Sprintf( field := fmt.Sprintf(
"%s: %s\n", fields.Key(), value) "%s: %s\n", fields.Key(), value)
pv.pagerin.Write([]byte(field)) _, err = pv.pagerin.Write([]byte(field))
if err != nil {
logging.Errorf("failed to write to stdin of pager: %v", err)
}
} }
// virtual header // virtual header
if len(info.Labels) != 0 { if len(info.Labels) != 0 {
labels := fmtHeader(info, "Labels", "") labels := fmtHeader(info, "Labels", "")
pv.pagerin.Write([]byte(fmt.Sprintf("Labels: %s\n", labels))) _, err := pv.pagerin.Write([]byte(fmt.Sprintf("Labels: %s\n", labels)))
if err != nil {
logging.Errorf("failed to write to stdin of pager: %v", err)
}
}
_, err := pv.pagerin.Write([]byte{'\n'})
if err != nil {
logging.Errorf("failed to write to stdin of pager: %v", err)
} }
pv.pagerin.Write([]byte{'\n'})
} }
} }
@ -689,7 +701,10 @@ func (pv *PartViewer) hyperlinks(r io.Reader) (reader io.Reader) {
func (pv *PartViewer) copyFilterOutToPager() { func (pv *PartViewer) copyFilterOutToPager() {
stdout, _ := pv.filter.StdoutPipe() stdout, _ := pv.filter.StdoutPipe()
stderr, _ := pv.filter.StderrPipe() stderr, _ := pv.filter.StderrPipe()
pv.filter.Start() err := pv.filter.Start()
if err != nil {
logging.Warnf("failed to start filter: %v", err)
}
ch := make(chan interface{}) ch := make(chan interface{})
go func() { go func() {
defer logging.PanicHandler() defer logging.PanicHandler()
@ -718,7 +733,10 @@ func (pv *PartViewer) copyFilterOutToPager() {
<-ch <-ch
<-ch <-ch
pv.filter.Wait() err := pv.filter.Wait()
if err != nil {
logging.Warnf("failed to wait for the filter process: %v", err)
}
pv.pagerin.Close() pv.pagerin.Close()
}() }()
} }
@ -732,7 +750,10 @@ func (pv *PartViewer) copySourceToSinkStripAnsi() {
for scanner.Scan() { for scanner.Scan() {
text := scanner.Text() text := scanner.Text()
text = ansi.ReplaceAllString(text, "") text = ansi.ReplaceAllString(text, "")
io.WriteString(pv.sink, text+"\n") _, err := io.WriteString(pv.sink, text+"\n")
if err != nil {
logging.Warnf("failed write ", err)
}
} }
if err := scanner.Err(); err != nil { if err := scanner.Err(); err != nil {
fmt.Fprintf(os.Stderr, "failed to read line: %v\n", err) fmt.Fprintf(os.Stderr, "failed to read line: %v\n", err)
@ -819,7 +840,10 @@ func (pv *PartViewer) Draw(ctx *ui.Context) {
func (pv *PartViewer) Cleanup() { func (pv *PartViewer) Cleanup() {
if pv.pager != nil && pv.pager.Process != nil { if pv.pager != nil && pv.pager.Process != nil {
pv.pager.Process.Kill() err := pv.pager.Process.Kill()
if err != nil {
logging.Warnf("failed to kill pager process: %v", err)
}
pv.pager = nil pv.pager = nil
} }
} }

View file

@ -190,8 +190,14 @@ func (term *Terminal) Close(err error) {
term.pty = nil term.pty = nil
} }
if term.cmd != nil && term.cmd.Process != nil { if term.cmd != nil && term.cmd.Process != nil {
term.cmd.Process.Kill() err := term.cmd.Process.Kill()
term.cmd.Wait() if err != nil {
logging.Warnf("failed to kill process: %v", err)
}
err = term.cmd.Wait()
if err != nil {
logging.Warnf("failed for wait for process to terminate: %v", err)
}
term.cmd = nil term.cmd = nil
} }
if !term.closed && term.OnClose != nil { if !term.closed && term.OnClose != nil {
@ -277,7 +283,10 @@ func (term *Terminal) Draw(ctx *ui.Context) {
if ctx.Width() != cols || ctx.Height() != rows { if ctx.Width() != cols || ctx.Height() != rows {
term.writeMutex.Lock() term.writeMutex.Lock()
pty.Setsize(term.pty, &winsize) err := pty.Setsize(term.pty, &winsize)
if err != nil {
logging.Warnf("failed to set terminal size: %v", err)
}
term.vterm.SetSize(ctx.Height(), ctx.Width()) term.vterm.SetSize(ctx.Height(), ctx.Width())
term.writeMutex.Unlock() term.writeMutex.Unlock()
rect := vterm.NewRect(0, ctx.Width(), 0, ctx.Height()) rect := vterm.NewRect(0, ctx.Width(), 0, ctx.Height())

View file

@ -130,7 +130,7 @@ func (imapw *IMAPWorker) handleDirectoryThreaded(
// Only initialize if we are not filtering // Only initialize if we are not filtering
var uids []uint32 var uids []uint32
for i := len(aercThreads) - 1; i >= 0; i-- { for i := len(aercThreads) - 1; i >= 0; i-- {
aercThreads[i].Walk(func(t *types.Thread, level int, currentErr error) error { aercThreads[i].Walk(func(t *types.Thread, level int, currentErr error) error { //nolint:errcheck // error indicates skipped threads
uids = append(uids, t.Uid) uids = append(uids, t.Uid)
return nil return nil
}) })

View file

@ -87,7 +87,10 @@ func (md *mailboxContainer) Copy(dest, src string, uids []uint32) error {
if err != nil { if err != nil {
return fmt.Errorf("could not get flags for message with uid %d", uidSrc) return fmt.Errorf("could not get flags for message with uid %d", uidSrc)
} }
destmbox.Append(r, flags) err = destmbox.Append(r, flags)
if err != nil {
return fmt.Errorf("could not append data to mbox: %v", err)
}
} }
} }
md.mailboxes[dest] = destmbox md.mailboxes[dest] = destmbox

View file

@ -234,7 +234,11 @@ func (db *DB) msgModify(key string,
} }
defer msg.Close() defer msg.Close()
cb(msg) err = cb(msg)
if err != nil {
logging.Warnf("callback failed: %v", err)
}
err = msg.TagsToMaildirFlags() err = msg.TagsToMaildirFlags()
if err != nil { if err != nil {
logging.Errorf("could not sync maildir flags: %v", err) logging.Errorf("could not sync maildir flags: %v", err)
@ -248,10 +252,16 @@ func (db *DB) MsgModifyTags(key string, add, remove []string) error {
err := db.msgModify(key, func(msg *notmuch.Message) error { err := db.msgModify(key, func(msg *notmuch.Message) error {
ierr := msg.Atomic(func(msg *notmuch.Message) { ierr := msg.Atomic(func(msg *notmuch.Message) {
for _, t := range add { for _, t := range add {
msg.AddTag(t) err := msg.AddTag(t)
if err != nil {
logging.Warnf("failed to add tag: %v", err)
}
} }
for _, t := range remove { for _, t := range remove {
msg.RemoveTag(t) err := msg.RemoveTag(t)
if err != nil {
logging.Warnf("failed to add tag: %v", err)
}
} }
}) })
return ierr return ierr

View file

@ -101,7 +101,7 @@ func getMaxUID(thread *Thread) uint32 {
// TODO: should we make this part of the Thread type to avoid recomputation? // TODO: should we make this part of the Thread type to avoid recomputation?
var Uid uint32 var Uid uint32
thread.Walk(func(t *Thread, _ int, currentErr error) error { _ = thread.Walk(func(t *Thread, _ int, currentErr error) error {
if t.Uid > Uid { if t.Uid > Uid {
Uid = t.Uid Uid = t.Uid
} }