Skip to content

Commit a47f8ae

Browse files
Merge pull request #109 from Clever/INFRANG-5529-truncate-errors
Bugfix: Limit length of error fields per AWS limits.
2 parents f5d3f8b + 7e62ec6 commit a47f8ae

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

VERSION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
v0.7.1
2-
Add team tag to activities
1+
v0.7.2
2+
Truncate error messages to fit within AWS limits.

cmd/sfncli/error_names.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"fmt"
5+
"strings"
56

67
"github.com/aws/aws-sdk-go/aws"
78
"github.com/aws/aws-sdk-go/service/sfn"
@@ -26,11 +27,15 @@ type TaskFailureError interface {
2627
func (t TaskRunner) sendTaskFailure(err TaskFailureError) error {
2728
t.logger.ErrorD("send-task-failure", logger.M{"name": err.ErrorName(), "cause": err.ErrorCause()})
2829

30+
// Limits from https://docs.aws.amazon.com/step-functions/latest/apireference/API_SendTaskFailure.html
31+
const maxErrorLength = 256
32+
const maxCauseLength = 32768
33+
2934
// don't use SendTaskFailureWithContext, since the failure itself could be from the parent
3035
// context being cancelled, but we still want to report to AWS the failure of the task.
3136
_, sendErr := t.sfnapi.SendTaskFailure(&sfn.SendTaskFailureInput{
32-
Error: aws.String(err.ErrorName()),
33-
Cause: aws.String(err.ErrorCause()),
37+
Error: aws.String(truncateString(err.ErrorName(), maxErrorLength, "[truncated]")),
38+
Cause: aws.String(truncateString(err.ErrorCause(), maxCauseLength, "[truncated]")),
3439
TaskToken: &t.taskToken,
3540
})
3641
if sendErr != nil {
@@ -39,6 +44,20 @@ func (t TaskRunner) sendTaskFailure(err TaskFailureError) error {
3944
return err
4045
}
4146

47+
// Returns its input truncated to maxLength, with the ability to replace the end to indicate truncation.
48+
//
49+
// For example, truncateString(s, l, "") just truncates to length l. But truncateString(s, l, "xy") will
50+
// first truncate to length l, then replace the last two characters with "xy"
51+
func truncateString(s string, maxLength int, truncationIndicatorSuffix string) string {
52+
if len(s) <= maxLength {
53+
return s
54+
}
55+
// when we cut out some number of bytes from the end, we may be cutting in the middle of a multi-byte unicode char
56+
// if so, we can use ToValidUTF8 to trim it a teeny bit further to eliminate the whole char.
57+
// (Note, this does mean invalid UTF8 inputs will see more changes than expected, but we won't worry about that)
58+
return strings.ToValidUTF8(s[:maxLength-len(truncationIndicatorSuffix)], "") + truncationIndicatorSuffix
59+
}
60+
4261
// TaskFailureUnknown is used for any error that is unexpected or not understood completely.
4362
type TaskFailureUnknown struct {
4463
error

0 commit comments

Comments
 (0)