Skip to content

Commit d51e9b1

Browse files
committed
Fix lipgloss padding on long CLI error messages
1 parent a13e39b commit d51e9b1

1 file changed

Lines changed: 23 additions & 13 deletions

File tree

internal/command/result.go

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ import (
3838

3939
// Error styling
4040
var (
41-
errorStyle = branding.ErrorStyle
42-
errorMessageStyle = branding.ErrorStyle
43-
suggestionStyle = branding.GreenStyle.Copy().Italic(true)
44-
descriptionStyle = branding.GrayStyle.Copy().Bold(true)
41+
errorStyle = branding.ErrorStyle
42+
suggestionStyle = branding.GreenStyle.Copy().Italic(true)
4543
)
4644

4745
// Result interface describes all the formats for the result output.
@@ -140,6 +138,18 @@ func filterResultValue(result Result, filter string) (any, error) {
140138
return value, nil
141139
}
142140

141+
// renderErrorMsg unescapes literal \n sequences and styles each line
142+
// individually — passing a multiline string to lipgloss causes it to pad every
143+
// line to the width of the longest one, producing unreadable trailing spaces.
144+
func renderErrorMsg(msg string) string {
145+
msg = strings.ReplaceAll(msg, `\n`, "\n")
146+
lines := strings.Split(msg, "\n")
147+
for i, line := range lines {
148+
lines[i] = branding.ErrorStyle.Render(line)
149+
}
150+
return strings.Join(lines, "\n")
151+
}
152+
143153
// handleError handle errors returned from command execution, try to understand why error happens and offer help to the user.
144154
func handleError(description string, err error) {
145155
if err == nil {
@@ -151,38 +161,38 @@ func handleError(description string, err error) {
151161
switch t := err.(type) {
152162
case *grpc.RPCError:
153163
errorMsg := errorStyle.Render(fmt.Sprintf("%s Grpc Error:", output.ErrorEmoji()))
154-
detailMsg := errorMessageStyle.Render(t.GRPCStatus().Err().Error())
164+
detailMsg := renderErrorMsg(t.GRPCStatus().Err().Error())
155165
_, _ = fmt.Fprintf(os.Stderr, "%s %s\n", errorMsg, detailMsg)
156166
default:
157167
if errors.Is(err, config.ErrOutdatedFormat) {
158168
errorMsg := errorStyle.Render(fmt.Sprintf("%s Config Error:", output.ErrorEmoji()))
159-
detailMsg := errorMessageStyle.Render(err.Error())
169+
detailMsg := renderErrorMsg(err.Error())
160170
_, _ = fmt.Fprintf(os.Stderr, "%s %s\n", errorMsg, detailMsg)
161171

162172
suggestion := suggestionStyle.Render(fmt.Sprintf("%s Please reset configuration using: 'flow init --reset'. Read more about new configuration here: https://github.com/onflow/flow-cli/releases/tag/v0.17.0", output.TryEmoji()))
163173
_, _ = fmt.Fprintf(os.Stderr, "%s\n", suggestion)
164174
} else if errors.Is(err, config.ErrDoesNotExist) {
165175
errorMsg := errorStyle.Render(fmt.Sprintf("%s Config Error:", output.ErrorEmoji()))
166-
detailMsg := errorMessageStyle.Render(err.Error())
176+
detailMsg := renderErrorMsg(err.Error())
167177
_, _ = fmt.Fprintf(os.Stderr, "%s %s\n", errorMsg, detailMsg)
168178

169179
suggestion := suggestionStyle.Render(fmt.Sprintf("%s Please create configuration using: flow init", output.TryEmoji()))
170180
_, _ = fmt.Fprintf(os.Stderr, "%s\n", suggestion)
171181
} else if strings.Contains(err.Error(), "transport:") {
172182
errorMsg := errorStyle.Render(fmt.Sprintf("%s Connection Error:", output.ErrorEmoji()))
173-
detailMsg := errorMessageStyle.Render(strings.Split(err.Error(), "transport:")[1])
183+
detailMsg := renderErrorMsg(strings.Split(err.Error(), "transport:")[1])
174184
_, _ = fmt.Fprintf(os.Stderr, "%s %s\n", errorMsg, detailMsg)
175185

176186
suggestion := suggestionStyle.Render(fmt.Sprintf("%s Make sure your emulator is running or connection address is correct.", output.TryEmoji()))
177187
_, _ = fmt.Fprintf(os.Stderr, "%s\n", suggestion)
178188
} else if strings.Contains(err.Error(), "NotFound desc =") {
179189
errorMsg := errorStyle.Render(fmt.Sprintf("%s Not Found:", output.ErrorEmoji()))
180-
detailMsg := errorMessageStyle.Render(strings.Split(err.Error(), "NotFound desc =")[1])
190+
detailMsg := renderErrorMsg(strings.Split(err.Error(), "NotFound desc =")[1])
181191
_, _ = fmt.Fprintf(os.Stderr, "%s%s\n", errorMsg, detailMsg)
182192
} else if strings.Contains(err.Error(), "code = InvalidArgument desc = ") {
183193
desc := strings.Split(err.Error(), "code = InvalidArgument desc = ")
184194
errorMsg := errorStyle.Render(fmt.Sprintf("%s Invalid argument:", output.ErrorEmoji()))
185-
detailMsg := errorMessageStyle.Render(desc[len(desc)-1])
195+
detailMsg := renderErrorMsg(desc[len(desc)-1])
186196
_, _ = fmt.Fprintf(os.Stderr, "%s %s\n", errorMsg, detailMsg)
187197

188198
if strings.Contains(err.Error(), "is invalid for chain") {
@@ -194,21 +204,21 @@ func handleError(description string, err error) {
194204
}
195205
} else if strings.Contains(err.Error(), "invalid signature:") {
196206
errorMsg := errorStyle.Render(fmt.Sprintf("%s Invalid signature:", output.ErrorEmoji()))
197-
detailMsg := errorMessageStyle.Render(strings.Split(err.Error(), "invalid signature:")[1])
207+
detailMsg := renderErrorMsg(strings.Split(err.Error(), "invalid signature:")[1])
198208
_, _ = fmt.Fprintf(os.Stderr, "%s %s\n", errorMsg, detailMsg)
199209

200210
suggestion := suggestionStyle.Render(fmt.Sprintf("%s Check the signer private key is provided or is in the correct format. If running emulator, make sure it's using the same configuration as this command.", output.TryEmoji()))
201211
_, _ = fmt.Fprintf(os.Stderr, "%s\n", suggestion)
202212
} else if strings.Contains(err.Error(), "signature could not be verified using public key with") {
203213
errorMsg := errorStyle.Render(fmt.Sprintf("%s %s:", output.ErrorEmoji(), description))
204-
detailMsg := errorMessageStyle.Render(err.Error())
214+
detailMsg := renderErrorMsg(err.Error())
205215
_, _ = fmt.Fprintf(os.Stderr, "%s %s\n", errorMsg, detailMsg)
206216

207217
suggestion := suggestionStyle.Render(fmt.Sprintf("%s If you are running emulator locally make sure that the emulator was started with the same config as used in this command. \nTry restarting the emulator.", output.TryEmoji()))
208218
_, _ = fmt.Fprintf(os.Stderr, "%s\n", suggestion)
209219
} else {
210220
errorMsg := errorStyle.Render(fmt.Sprintf("%s %s:", output.ErrorEmoji(), description))
211-
detailMsg := errorMessageStyle.Render(err.Error())
221+
detailMsg := renderErrorMsg(err.Error())
212222
_, _ = fmt.Fprintf(os.Stderr, "%s %s\n", errorMsg, detailMsg)
213223
}
214224
}

0 commit comments

Comments
 (0)