我需要检查Go代码中的值是否为空吗?

问题描述 投票:0回答:2

我正在使用下面的代码在客户端删除sqs消息。

if resp, err := s.client.DeleteMessageBatch(context.TODO(), &sqs.DeleteMessageBatchInput{
    Entries:  entries,
    QueueUrl: s.url,
}); err != nil {
    return fmt.Errorf("failed to DeleteMessageBatch, %v, %v", err, resp.Failed)
}

由于你不需要看整个代码,所以我写了部分代码。

如你所见,当 err 不为 nil 时,我调用了

DeleteMessageBatchInput
并打印了错误消息。

假设调用时出现网络问题,则 err 不为 nil。 在这种情况下,

resp.Failed
可以有空值,从而导致内存问题?

如果是这样,我是否需要为上述情况编写一些防御代码?

任何帮助将不胜感激。

谢谢。

go amazon-sqs
2个回答
0
投票

请参阅删除消息批次
失败有两种情况。
第一个 http 200 和失败的数组。
第二个 http 不是 200,只会出现错误。
所以你可以这样写

resp, err := s.client.DeleteMessageBatch(context.TODO(), &sqs.DeleteMessageBatchInput{
    Entries:  entries,
    QueueUrl: s.url,
})
if err != nil {
    return fmt.Errorf("failed to DeleteMessageBatch, %v", err)
}
if len(resp.Failed) > 0 {
    return fmt.Errorf("failed to DeleteMessageBatch, %v", resp.Failed)
}

0
投票

一般来说,约定是当返回错误时,其余值无效。如果您查看代码,您会返回错误或结果:

    result, err := ...
    if err != nil {
        return nil, err
    }
    ...

    return result, nil

对于您遇到的任何正常代码来说通常都是如此。

所以你不必在错误情况下测试

resp
任何东西,你根本不应该使用它。您的代码将不可避免地因空指针异常而恐慌。

文档指出,您应该检查对 Client.DeleteMessageBatch

successful 调用是否存在批处理错误。如果调用失败,您实际上无法确定,因为不清楚错误发生在哪里(例如,批处理可能已成功,但由于网络错误而您没有收到响应)。

如果您有更复杂的错误处理,您可以返回一个错误,表明整个操作失败或哪些条目受到影响。

对于部分失败,定义您自己的错误类型,例如:

type EntryDeletionError struct {
    Failed []types.BatchResultErrorEntry
}

func (e EntryDeletionError) Error() string {
    var b strings.Builder

    b.WriteString("deletion failed for: ")
    first := true
    for _, f := range e.Failed {
        if first {
            b.WriteString(", ")
            first = false
        }
        b.WriteString(*f.Id)
    }

    return b.String()
}

并在你的函数中使用它:

    resp, err := s.client.DeleteMessageBatch(context.TODO(), &sqs.DeleteMessageBatchInput{
        Entries:  entries,
        QueueUrl: s.url,
    })

    switch {
    case err != nil:
        return fmt.Errorf("deleting entries failed: %w", err)

    case len(resp.Failed) > 0:
        return EntryDeletionError{resp.Failed}
    }

    return nil

请注意,您应该用 %w

包裹丰富的错误
,而不是
%v

© www.soinside.com 2019 - 2024. All rights reserved.