Skip to content

Commit 3fb95ae

Browse files
committed
Merge branch 'main' into origin/dev
2 parents 086e0c8 + bab05eb commit 3fb95ae

7 files changed

Lines changed: 172 additions & 32 deletions

File tree

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Havlik Marcell
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Project.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
name = "RelevanceStacktrace"
22
uuid = "6c8a4c8a-cd07-4735-95b7-b1ced2eaf8fd"
3-
authors = ["Your Name <you@example.com>"]
4-
version = "1.0.1"
3+
authors = ["Marcell Havlik <havlikmarcell@gmail.com>"]
4+
version = "0.1.8"
5+
6+
[compat]
7+
julia = "^1.7"

README.md

Lines changed: 82 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,105 @@
11
# RelevanceStacktrace.jl
2-
Julia relevance Stacktrace.
2+
**Find the error as fast as possible!**
33

4-
# Goal
5-
What are you searching during development?
6-
99% of the time for the **TOP error of the stacktrace from your project's files**. >> **So it highlights it! :)**
7-
1% you can use the unhighlighted parts. :)
4+
Most important elements in the stacktrace:
5+
1. error **source file that you edit**
6+
1. **file + filename + line number**
7+
2. function name
8+
3. stack depth counter
9+
4. modul name
10+
2. other project files
11+
3. other internal files
12+
13+
So let's design it like this! -> RelevanceStacktrace
814

915
# Why
10-
Julia stacktrace is for finding error. Why don't we use it to help us right? ;)
1116

12-
# Usage
13-
Many way... but easiest:
17+
**Stacktrace is for locating the error. Let's FOCUS ONLY on that.**
18+
19+
With this package in the past years I literally forgot what does searching for error is as I just click on the **BOLD GREEN** filename with a ctrl + click in vscode each time.
20+
21+
**Green!** Because locating the error is a good thing. Not bad! So "Julia locate the right file and highlight it for us! ;) "
22+
23+
I think 99% of the time the error will be in the **the first error of the stacktrace from your project's files**. >> **So it highlights it! :)**
1424

15-
`include(path_to_file * "RelevanceStacktrace.jl/src/RelevanceStacktrace.jl")`
25+
Any other time you will always have the unhighlighted parts. :)
1626

17-
or terminal
27+
# Demo
28+
Artificial error, to see it's power:
29+
```
30+
using RelevanceStacktrace
31+
func4(x) = begin
32+
x+=x
33+
x=sum(x) .* [5, 3]
34+
x=sum(x[3])
35+
return x/3
36+
end
37+
func3(x) = x+5 + func4(x)
38+
func2(x) = x+3 + func3(x)
39+
func1(x) = begin
40+
func2(x)
41+
end
42+
func1(3)
43+
```
44+
![artificial error example](/assets/artificial_error.png)
45+
In real life example it is even more useful.
1846

47+
Long stacktrace error:
48+
```
49+
sum([])
1950
```
20-
julia
51+
![long internal error example](/assets/sum([])_error.png)
52+
This is still nice I think, but to be honest RelevanceStacktrace shines better when the error is in some of your project file.
53+
54+
# INSTALL
55+
56+
Many way... but easiest:
57+
58+
```julia
2159
] add https://github.com/Cvikli/RelevanceStacktrace.jl.git
22-
then: using RelevanceStacktrace
60+
using RelevanceStacktrace
2361
```
2462

25-
or from a folder next to the cloned repo you can try using this version
63+
or
2664

65+
```julia
66+
include(path_to_file * "RelevanceStacktrace.jl/src/RelevanceStacktrace.jl")
67+
using .RelevanceStacktrace
2768
```
69+
70+
or from a folder next to the cloned repo you can try using this version
71+
72+
```julia
2873
push!(LOAD_PATH, "../RelevanceStacktrace.jl/"); Base.load_path()
2974
using RelevanceStacktrace
3075
```
31-
32-
But for me it doesn't perform well in certain situation, which I didn't have time to figure out... It only loads the package for the second time in this case...
76+
or
77+
```
78+
using Pkg; Pkg.add(url="https://github.com/Cvikli/RelevanceStacktrace.jl.git")
79+
using RelevanceStacktrace
80+
```
3381

3482
# Fun fact
35-
**Debug the Debug.** :D We catch the error in the error handling and do a very basic error printing mechanism, so we can debug the backtrace printing error.
36-
We overloaded the Base.print_stackframe... so basically any stackprinting will be changed with this method. :)
83+
84+
**Debug the Debug.** :D We catch the error in the error handling and do a very basic error printing mechanism, so we can debug the backtrace printing error.
3785

3886
**The relevant errors are green, because finding one is a good thing!** ;)
3987

88+
**Fallback to raw stacktrace printing.** As the project is sort of experimental, if a special case happen that we just don't bother to handle, it will fall back to print it in a basic format.
89+
90+
# Future works?
91+
**Module names are useless.** Actually we could drop the modul names as it just waste of space
92+
93+
**Function param types are pretty useless.** Maybe we could just show function names and parameters::types if it is actually matters... (As it is used very very rarely!)
94+
95+
**AbbreviatedStackTraces sounds interesting** We could merge it into this project with an optional flag maybe later on?
96+
97+
# Great stacktraces
98+
- AbbreviatedStackTraces: great project. :) https://github.com/BioTurboNick/AbbreviatedStackTraces.jl As UX decision I didn't merged it as the variation of stacktrace can create interruption in the thinking. We expect the output to be always the same. But of course more test should be done if someone believe it can be useful.
99+
- ClearStacktrace: was great for inspiration! https://github.com/jkrumbiegel/ClearStacktrace.jl
100+
40101
# Note
41-
(**only tested on Ubuntu for Julia 1.6!** )
102+
103+
(**only tested on Ubuntu for Julia 1.8!** )
104+
105+
(**later version was tested on Ubuntu for Julia 1.6 and 1.7!** )

assets/artificial_error.png

74 KB
Loading

assets/sum([])_error.png

218 KB
Loading

src/RelevanceStacktrace.jl

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
module RelevanceStacktrace
22
import Base: find_source_file, show_full_backtrace, StackFrame, fixup_stdlib_path,
3-
stacktrace_expand_basepaths, stacktrace_contract_userdir, contractuser
3+
stacktrace_expand_basepaths, stacktrace_contract_userdir, contractuser, something
44

5-
KNOWN_MODULES = ["VSCodeServer", "Core", "Distributed"]
6-
KNOWN_MODULES_PATHS_1 = ["."]
7-
KNOWN_MODULES_PATHS_2 = [".vscode", ".julia", "buildworker"]
5+
const KNOWN_MODULES = ["VSCodeServer", "Core", "Distributed"]
6+
const KNOWN_MODULES_PATHS_BASE = ["."]
7+
const KNOWN_MODULES_PATHS = [".vscode", ".julia", "buildworker"]
88

99
is_project_file(modul, pathparts) = (
1010
!(string(modul) in KNOWN_MODULES) &&
11-
!(pathparts[1] in KNOWN_MODULES_PATHS_1) &&
12-
!(length(pathparts)>1 && pathparts[2] in KNOWN_MODULES_PATHS_2))
11+
!(pathparts[1] in KNOWN_MODULES_PATHS_BASE) &&
12+
!any(pathpart in KNOWN_MODULES_PATHS for pathpart in pathparts))
1313

1414
# This is useful because of
1515
function print_stackframe_relevance(io, i, frame::Base.StackFrame, n::Int, digit_align_width, modulecolordict, ownmodulescounter)
@@ -82,7 +82,8 @@ function print_stackframe_relevance_print(io, i, frame::Base.StackFrame, n::Int,
8282
end
8383

8484

85-
function Base.show_full_backtrace(io::IO, trace::Vector; print_linebreaks::Bool)
85+
Base.show_full_backtrace(io::IO, trace::Vector; print_linebreaks::Bool) = show_full_backtrace_relevance(io, trace, print_linebreaks)
86+
function show_full_backtrace_relevance(io::IO, trace, print_linebreaks::Bool)
8687
num_frames = length(trace)
8788
ndigits_max = ndigits(num_frames)
8889

@@ -92,12 +93,16 @@ function Base.show_full_backtrace(io::IO, trace::Vector; print_linebreaks::Bool)
9293
println(io, "\nStacktrace:")
9394

9495
try
95-
for (i, (frame, n)) in enumerate(trace)
96+
trace_fix = convert(Vector{Tuple{StackFrame, Int}}, trace)
97+
i=1
98+
while length(trace_fix) >= i
99+
frame, n = trace_fix[i]
96100
print_stackframe_relevance(io, i, frame, n, ndigits_max, modulecolordict, ownmodulescounter)
97101
if i < num_frames
98102
println(io)
99103
print_linebreaks && println(io)
100104
end
105+
i+=1
101106
end
102107
catch e
103108
println(io)

test/RelevanceStacktrace.test.jl

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ using Revise
66
includet("../src/RelevanceStacktrace.jl")
77

88

9-
func4(x) = x .* ["32", 3]
9+
func4(x) = begin
10+
x+=x
11+
x=sum(x) .* [5, 3]
12+
x=sum(x[3])
13+
return x/3
14+
end
1015
func3(x) = x+5 + func4(x)
1116
func2(x) = x+3 + func3(x)
1217
func1(x) = begin
@@ -15,17 +20,59 @@ end
1520
func1(3)
1621

1722
#%%
23+
show_full_backtrace(io::IO, trace::Vector{Tuple{Base.StackTraces.StackFrame, Int}}; print_linebreaks::Bool)
24+
#%%
25+
using Plots
26+
using BenchmarkTools, Plots
27+
plot([1,2,3], seriestype=:blah)
28+
# @btime plot([1,2,3], seriestype=:blah)
29+
#%%
30+
sum([])
31+
#%%
32+
33+
# func4(x) = x .* ["32", 3]
34+
# func3(x) = x+5 + func4(x)
35+
# func2(x) = x+3 + func3(x)
36+
# func1(x) = begin
37+
# func2(x)
38+
# end
39+
# func1(3)
40+
using Base: stacktrace_linebreaks, process_backtrace, StackFrame
41+
using .RelevanceStacktrace: show_full_backtrace_relevance
1842
try
19-
eval(Meta.parse("invalidfn()"))
43+
# eval(Meta.parse("invalidfn()"))
44+
func1(3)
2045
catch e
46+
# x= process_backtrace(catch_backtrace())
47+
# @show x
48+
# for (f,i) in x
49+
# @show typeof(f)
50+
# @show typeof(i)
51+
# end
52+
# @show e
53+
# @show process_backtrace(catch_backtrace())
54+
# @show "eq"
55+
# @show convert(Vector{Tuple{StackFrame, Int}}, process_backtrace(catch_backtrace()))
56+
@code_warntype show_full_backtrace_relevance(stdout, process_backtrace(catch_backtrace()), false)
2157
# @edit showerror(stdout, e, catch_backtrace())
2258
# showerror(stdout, e)
23-
@edit Base.show_backtrace(stdout, catch_backtrace())
59+
# @edit Base.show_backtrace(stdout, catch_backtrace())
2460
end
2561
#%%
62+
@code_warntype catch_backtrace()
63+
#%%
64+
typeof(catch_backtrace())
65+
#%%
66+
process_backtrace(catch_backtrace())
67+
#%%
68+
using Base: stacktrace_linebreaks,process_backtrace
69+
stacktrace_linebreaks()
70+
#%%
71+
72+
process_backtrace(catch_backtrace())
2673

27-
Base.show_full_backtrace(io, filtered; print_linebreaks = stacktrace_linebreaks())
2874
#%%
75+
error("bla")
2976
#%%
3077

3178

0 commit comments

Comments
 (0)