Sublime Forum

How to capture errors and warnings properly with ExecCommand subclass

#1

Hi,

Right now I’ve subclassed ExecCommand and i want to extend the functionality of the on_finish method to fit my needs:

def finish(self, proc):
    print('-'*80)
    sublime.log_result_regex(True)
    super().finish(proc)
    sublime.log_result_regex(False)
    print('-'*80)
    exit_code = proc.exit_code()
    errs = self.output_view.find_all_results()
    print(errs)
    print('-'*80)

    if exit_code == 0 or exit_code is None:
        ... EXTRA STUFF DEPENDING OF ERRORS&WARNINGS ...

here’s the thing, I got at my disposal 2 sources of information, exit_code = proc.exit_code() and errs = self.output_view.find_all_results(), with those 2 variables theorically i can have a decent control of what happened with the process, but… i want more, I’d like to know which are exactly the errors and which are the warnings, right now my file_regex looks like this:

"file_regex": "^(?:\\.{2}\\\\)*([a-z]?:?[^\\(\n]+)\\(([^\\)]+)\\): ([^\n]+)"

But this one doesn’t distinguish between errors/warnings, it captures everything, let’s say i got this source file:

#include <stdio.h>

#pragma message ("this\\is\\a\\path(3): warning C666: i'm a random warning")
#pragma message ("this\\is\\a\\path(4): error C666: i'm a random error")

int main(int argc, char* argv[]) {
}

If I run it, the pasted subclassed on_finish pasted above would print:

--------------------------------------------------------------------------------
found result file, line, col of [this\is\a\path], [3], [warning C666: i'm a random warning] full path: /C/Users/KneDa/Desktop/st_forum_issue/this/is/a/path
found result file, line, col of [this\is\a\path], [4], [error C666: i'm a random error] full path: /C/Users/KneDa/Desktop/st_forum_issue/this/is/a/path
--------------------------------------------------------------------------------
[('/C/Users/KneDa/Desktop/st_forum_issue/this/is/a/path', 3, 0), ('/C/Users/KneDa/Desktop/st_forum_issue/this/is/a/path', 4, 0)]
--------------------------------------------------------------------------------

Which btw, it’s kind of strange… why do the errs variable doesn’t contain the warning messages and the log_result_regex it does O_o?

Anyway, question is, how can i capture and distinguish between errors/warnings?

warnings: "file_regex": "^(?:\\.{2}\\\\)*([a-z]?:?[^\\(\n]+)\\(([^\\)]+)\\): warning ([^\n]+)"
errors: "file_regex": "^(?:\\.{2}\\\\)*([a-z]?:?[^\\(\n]+)\\(([^\\)]+)\\): error ([^\n]+)" of

Thanks in advance

1 Like

How to replace dots (.) with slashes (/) when using `file_regex`?
#2

I believe we just solved this particular problem on the IRC channel, but just to bring the result back here for future people searching for this sort of thing, I’m posting the answer here as well.


The self.output_view.find_all_results() call returns to you a list of tuple that give you the position location of the results only:

[
    ('/home/tmartin/my_exec_test.c', 3, 2), 
    ('/home/tmartin/my_exec_test.c', 11, 5)
]

As seen here, you get to see that the regex captured two results and you get told (filename, row, column) information for the location of the errors, but you don’t get the results of the errors themselves.

In order to get that, you should use self.output_view.find_all_results_with_text() instead, which returns list of tuple that also includes the captured message as well as the other information:

[
    ('/home/tmartin/my_exec_test.c', 3, 2, 'warning: #warning this is a warning'), 
    ('/home/tmartin/my_exec_test.c', 11, 5, "error: expected ';' before 'return'")
]

For the case of an ExecCommand subclass, self.errs_by_file is also set up, which gives you a dict that keys on the file names with issues and provides values that give you the error information:

{
    '/home/tmartin/my_exec_test.c': [
        (3, 2, 'warning: #warning this is a warning'), 
        (11, 5, "error: expected ';' before 'return'")
    ]
}

Note however that this is something that the exec command does only when you have the option to display errors inline turned on, since it’s used to set up the phantoms for inline errors. When the user has that option turned off, this dictionary is always empty. As such you probably want to use find_all_results_with_text() instead.

4 Likes