# JPL: error after consulting a file not throwing exception

**URL:** <https://swi-prolog.discourse.group/t/jpl-error-after-consulting-a-file-not-throwing-exception/3660>\
**Category:** Tools\
**Tags:** how-to\
**Created:** [March 1, 2021, 8:21am UTC](https://swi-prolog.discourse.group/t/jpl-error-after-consulting-a-file-not-throwing-exception/3660 "2021-03-01T08:21:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![nspan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/nspan/32/3326_2.png) [@nspan](https://swi-prolog.discourse.group/u/nspan)\
**Post date:** [March 1, 2021, 8:21am UTC](https://swi-prolog.discourse.group/t/jpl-error-after-consulting-a-file-not-throwing-exception/3660/1 "2021-03-01T08:21:58Z")

</div>

Hi guys,

When I use JPL (from JavaSE 1.8), Prolog (SWI-Prolog version 8.2.2) can return an error message without throwing an exception. E.g. when using consult and the file has errors:

```prolog
import org.jpl7.Query;

public class Test {
  public static void main(String[] args) {
    try {
      String t1 = "consult('test.pl')";
      Query q1 = new Query(t1);
      q1.hasNext();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

```

I get the output at the console:

```prolog
ERROR: test.pl:1:23: Syntax error: Unexpected end of file

```

But no exception is thrown. Therefore my Java program cannot know that the consulted file has errors. The file _test.pl_ that I used in this simple example only contains a simple predicate with a syntactical error:

```prolog
brother(mike, stella)..

```

Can I do something so that my Java program can catch this error?  
Can I use another method to find and return the syntactical errors in the file that I intend to consult?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 1, 2021, 9:03am UTC](https://swi-prolog.discourse.group/t/jpl-error-after-consulting-a-file-not-throwing-exception/3660/2 "2021-03-01T09:03:14Z")

</div>

Compiling does not break at the first error. I think that is also what we want as it makes debugging a bit cumbersome if we can only deal with one error at a time.

What you can do is intercept the errors, e.g.,

```prolog
:- dynamic error_happened/1.

user:message_hook(Term, error, _Lines) :-
    assertz(error_happened(Term)),
    fail. % still print the error.

```

Now, after the load, you can call `error_happened/1` to see whether some error happened. Depending on your policies you can do many more things. You can also handle warnings. You can abort the current compilation on the first or after N errors/warnings using abort/0. That probably will get reported by JPL as an exception. Note that breaking out of a compilation is currently unsafe in the sense that it may not clean up all global state associated with the compiler. You should normally terminate and restart the process after breaking out of a compilation using abort/0.

---

<div class="post-metadata">

**Author:** ![ssardina](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ssardina/32/189_2.png) [@ssardina](https://swi-prolog.discourse.group/u/ssardina)\
**Post date:** [February 26, 2023, 11:17am UTC](https://swi-prolog.discourse.group/t/jpl-error-after-consulting-a-file-not-throwing-exception/3660/3 "2023-02-26T11:17:05Z")

</div>

I found this answer great and very useful, even applicable when using `swiplserver` for Python, same issue, consult does not abort with error. 👏

Just if someone is reading/using jan’s solution, see there is a typo in the `error_happend` inside the `assertz`, should be `assertz(error_happened(Term))`, that’s all 🙂 Otherwise you will look for the error predicate and won’t be there (but won´t give error either because it has been defined dynamic)

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [February 26, 2023, 11:22am UTC](https://swi-prolog.discourse.group/t/jpl-error-after-consulting-a-file-not-throwing-exception/3660/4 "2023-02-26T11:22:37Z")

</div>

> [@ssardina](#):
>
> should be `assertz(error_happened(Term))`

Thanks. I edited it for him.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [February 26, 2023, 11:50am UTC](https://swi-prolog.discourse.group/t/jpl-error-after-consulting-a-file-not-throwing-exception/3660/5 "2023-02-26T11:50:56Z")

</div>

It is still valid. Since come time there are also the commandline options `--on-warning` and `--on-error` that control the Prolog flags `on_warning` an `on_error`. The values are `print` (default), `halt` (halt immediately with status 1) or `status`, which implies keep running but on halt exit with status 1. See [SWI-Prolog -- Manual](https://www.swi-prolog.org/pldoc/man?section=flags#flag:on_error)

---

<div class="post-metadata">

**Author:** ![ssardina](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ssardina/32/189_2.png) [@ssardina](https://swi-prolog.discourse.group/u/ssardina)\
**Post date:** [February 27, 2023, 10:02am UTC](https://swi-prolog.discourse.group/t/jpl-error-after-consulting-a-file-not-throwing-exception/3660/6 "2023-02-27T10:02:44Z")

</div>

You are right @jan , I saw those CLI options and played with them, but your solution above is more general it seems to me; for example I can raise an exception after compilation (but not exit).

---

<div class="post-metadata">

**Author:** ![GeoffChurch](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/geoffchurch/32/4307_2.png) [@GeoffChurch](https://swi-prolog.discourse.group/u/GeoffChurch)\
**Post date:** [August 27, 2024, 4:53pm UTC](https://swi-prolog.discourse.group/t/jpl-error-after-consulting-a-file-not-throwing-exception/3660/7 "2024-08-27T16:53:11Z")

</div>

My use case is making sure that a term-expansion-based typechecker is throwing the right error during file consultation. In each test case I load a file, collect the error, and then unload the file. The following seems to work well (maybe there are improvements?):

```prolog
:- dynamic error_happened/1.

file_error(File, Error) :-
    assertz((user:message_hook(Term, error, _Lines) :-
                 assertz(error_happened(Term))), Ref),
    consult(File),
    $(retract(error_happened(Error))),
    erase(Ref),
    unload_file(File).

```
