diff --git a/base/strings/basic.jl b/base/strings/basic.jl index e4c88752a33d1..874101c361e7a 100644 --- a/base/strings/basic.jl +++ b/base/strings/basic.jl @@ -133,7 +133,7 @@ julia> isvalid(str, 2) false julia> str[2] -ERROR: StringIndexError("αβγdef", 2) +ERROR: StringIndexError: invalid index [2], valid nearby indices [1]=>'α', [3]=>'β' Stacktrace: [...] ``` diff --git a/base/strings/string.jl b/base/strings/string.jl index 89ec13fddef93..c267b263c66c9 100644 --- a/base/strings/string.jl +++ b/base/strings/string.jl @@ -11,6 +11,19 @@ struct StringIndexError <: Exception end @noinline string_index_err(s::AbstractString, i::Integer) = throw(StringIndexError(s, Int(i))) +function Base.showerror(io::IO, exc::StringIndexError) + s = exc.string + print(io, "StringIndexError: ", "invalid index [$(exc.index)]") + if firstindex(s) <= exc.index <= ncodeunits(s) + iprev = thisind(s, exc.index) + inext = nextind(s, iprev) + if inext <= ncodeunits(s) + print(io, ", valid nearby indices [$iprev]=>'$(s[iprev])', [$inext]=>'$(s[inext])'") + else + print(io, ", valid nearby index [$iprev]=>'$(s[iprev])'") + end + end +end const ByteArray = Union{Vector{UInt8},Vector{Int8}} diff --git a/doc/src/manual/strings.md b/doc/src/manual/strings.md index 02769108d7426..6c34b842a7c6a 100644 --- a/doc/src/manual/strings.md +++ b/doc/src/manual/strings.md @@ -279,11 +279,12 @@ julia> s[1] '∀': Unicode U+2200 (category Sm: Symbol, math) julia> s[2] -ERROR: StringIndexError("∀ x ∃ y", 2) +ERROR: StringIndexError: invalid index [2], valid nearby indices [1]=>'∀', [4]=>' ' +Stacktrace: [...] julia> s[3] -ERROR: StringIndexError("∀ x ∃ y", 3) +ERROR: StringIndexError: invalid index [3], valid nearby indices [1]=>'∀', [4]=>' ' Stacktrace: [...] @@ -303,7 +304,7 @@ julia> s[end-1] ' ': ASCII/Unicode U+0020 (category Zs: Separator, space) julia> s[end-2] -ERROR: StringIndexError("∀ x ∃ y", 9) +ERROR: StringIndexError: invalid index [9], valid nearby indices [7]=>'∃', [10]=>' ' Stacktrace: [...] @@ -323,7 +324,7 @@ julia> s[1:1] "∀" julia> s[1:2] -ERROR: StringIndexError("∀ x ∃ y", 2) +ERROR: StringIndexError: invalid index [2], valid nearby indices [1]=>'∀', [4]=>' ' Stacktrace: [...] diff --git a/test/strings/basic.jl b/test/strings/basic.jl index a34093fa4530e..9d553220e4b69 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -1076,3 +1076,12 @@ let x = SubString("ab", 1, 1) @test y === x chop("ab") === chop.(["ab"])[1] end + +@testset "show StringIndexError" begin + str = "abcdefghκijklmno" + e = StringIndexError(str, 10) + @test sprint(showerror, e) == "StringIndexError: invalid index [10], valid nearby indices [9]=>'κ', [11]=>'i'" + str = "κ" + e = StringIndexError(str, 2) + @test sprint(showerror, e) == "StringIndexError: invalid index [2], valid nearby index [1]=>'κ'" +end