Hi guys, I have quite a specific question. I would like to know how can I parse the error of the result of running a crystal script by the command Process.run ?
Basically, I need to get the line number where the problem occurred, and get the error message. Because the ouput is formatted with colors and other things, I don’t know how to do ?
Because then I would like to show something else based on the information I have got.
So from that beginning, how should I do then ?
processResult = IO::Memory.new
process = Process.run( "crystal error.cr",
error: processResult,
#error: :inherit,
shell: true)
Best bet would prob doing something like:
output = IO::Memory.new
Process.run "crystal", ["run", "--no-color", "error.cr"], error: output
output_string = output.to_s
# Parse the data from output_string somehow
This’ll at least remove the coloring, so will make writing a regex or parser easier.
There also is a -f json
option to output json instead of text.
I tried that, but didn’t seem to make a difference in this case.
When i run crystal run zzz.cr -f json
, where the file only contains asd
, then i get:
[{"file":"[snip]/zzz.cr","line":3,"column":1,"size":3,"message":"undefined local variable or method 'asd' for top-level"}]
1 Like
Ahh, seems the difference is it’ll be JSON if the error is a compile time error. If it’s a runtime exception, then it won’t be.
If @Fulgurance’s error is a compile time one, then this would be perfect! As it’s already in a consumable format. Otherwise if its a runtime error will have to parse that out somehow.
1 Like
Actually it’s a compile time errot I need ! So it’s perfect . Thanks a lot guys !
So I did that test but I get an error:
require "json"
class Output
property path : String
property line : Int32
property column : Int32
property size : Int32
property message : String
include JSON::Serializable
end
processResult = IO::Memory.new
process = Process.run( "crystal build error.cr -f json",
error: processResult,
#error: :inherit,
shell: true)
puts Output.from_json(processResult)
zohran@alienware-m17-r3:~/Downloads$ crystal test.cr
Unhandled exception: Expected BeginObject but was EOF at line 1, column 1
parsing Output at line 0, column 0 (JSON::SerializableError)
from /usr/share/crystal/src/json/serialization.cr:182:7 in 'initialize:__pull_for_json_serializable'
from test.cr:11:9 in 'new_from_json_pull_parser'
from test.cr:11:9 in 'new'
from /usr/share/crystal/src/json/from_json.cr:13:3 in 'from_json'
from test.cr:22:6 in '__crystal_main'
from /usr/share/crystal/src/crystal/main.cr:129:5 in 'main_user_code'
from /usr/share/crystal/src/crystal/main.cr:115:7 in 'main'
from /usr/share/crystal/src/crystal/main.cr:141:3 in 'main'
from /lib64/libc.so.6 in '??'
from /lib64/libc.so.6 in '__libc_start_main'
from /home/zohran/.cache/crystal/crystal-run-test.tmp in '_start'
from ???
Caused by: Expected BeginObject but was EOF at line 1, column 1 (JSON::ParseException)
from /usr/share/crystal/src/json/pull_parser.cr:705:5 in 'raise'
from /usr/share/crystal/src/json/pull_parser.cr:696:5 in 'expect_kind'
from /usr/share/crystal/src/json/pull_parser.cr:167:5 in 'read_begin_object'
from /usr/share/crystal/src/json/serialization.cr:182:7 in 'initialize:__pull_for_json_serializable'
from test.cr:11:9 in 'new_from_json_pull_parser'
from test.cr:11:9 in 'new'
from /usr/share/crystal/src/json/from_json.cr:13:3 in 'from_json'
from test.cr:22:6 in '__crystal_main'
from /usr/share/crystal/src/crystal/main.cr:129:5 in 'main_user_code'
from /usr/share/crystal/src/crystal/main.cr:115:7 in 'main'
from /usr/share/crystal/src/crystal/main.cr:141:3 in 'main'
from /lib64/libc.so.6 in '??'
from /lib64/libc.so.6 in '__libc_start_main'
from /home/zohran/.cache/crystal/crystal-run-test.tmp in '_start'
from ???
Okay got it, as usual, thanks a lot Blacksmoke16 !
I have one last question because I am facing a problem, is it normal sometime the field size of the json output return null instead of a Int ???
It’s nilable in the compiler, so guess so.
Okay so I will code something to manage that
Not sure what you mean by “code something to manage that”, you just need to make that field nilable too. E.g. getter size : Int32?
Yeah it’s what I mean 
But I think probably instead I will perform a gsub to ensure always that entry return a int. I don’t like to have variable with different types.
Keep it not nilable, but give it a default value of 0
or something then.