mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Some internal docs on buildmessage
This commit is contained in:
100
tools/tools-docs/buildmessage.md
Normal file
100
tools/tools-docs/buildmessage.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Build Message
|
||||
|
||||
We have a build process that does a lot of nested things. The build system
|
||||
should report errors in the process to the user: compilation problems, incorrect
|
||||
packages, etc.
|
||||
|
||||
We could have used exceptions but not only it would be hard to pass exceptions
|
||||
around, it also wouldn't be correct because users making mistakes is part of the
|
||||
expected use.
|
||||
|
||||
Also BuildMessage knows how to report errors better, recover on errors to
|
||||
collect as many errors in one pass as possible. For example, if several files
|
||||
fail to be parsed, we want to report all of them.
|
||||
|
||||
try/catch usually marks a code call and says "everything called from this try
|
||||
block, dynamically, is handled by this catch block". Build Message also has such
|
||||
property.
|
||||
|
||||
`buildmessage.capture` - takes a function and runs it in a buildmessage
|
||||
"context" and returns a message set (a set of errors). When the code is running
|
||||
inside that "capture", the errors from it go to this message set.
|
||||
|
||||
You can check if there were any errors by checking `messages.hasMessages()`.
|
||||
|
||||
There are different applications of `capture`, a lot of parts of the code wrap
|
||||
it. There is `captureAndExit` that exits immediately after printing. In catalog
|
||||
we have a wrapper that tries to run a function, if it has messages, refreshes
|
||||
the catalog and tries again.
|
||||
|
||||
In the lower-level code you usually never print the messages, you pass them up
|
||||
along the stack to be handled by something else (printing by cli or displaying
|
||||
by gui, etc).
|
||||
|
||||
`capture` is not useful without jobs. You use `buildmessage.enterJob` to create
|
||||
a new job. It has a title.
|
||||
|
||||
`buildmessage.error` is the function you use to say "something bad happened".
|
||||
The innermost job will provide more information to the error.
|
||||
Ex.: "While building package X: an error happened"
|
||||
|
||||
It should always be called inside a job. It will throw an exception if it is not
|
||||
inside, but you should not do this.
|
||||
|
||||
There is also a `buildmessage.exception`, the idea is, you use it to report the
|
||||
actual exceptions. Usually you use it to rethrow exceptions from a user package
|
||||
or a build plugin. It has some fancy stack-trace parsing and formatting.
|
||||
Ex.: "An exception while running your package.js file: TypeError ...".
|
||||
|
||||
Another function that you would run a lot is `job.hasMessages()`. Unlike
|
||||
exceptions, when you notify the buildmessage of errors, it doesn't stop the
|
||||
execution, it keeps going. This gives you an opportunity to recover and go on to
|
||||
get more errors. But if you don't want to keep going, you can check if there are
|
||||
any errors in the current job by calling `job.hasMessages()`. This call also
|
||||
includes messages from nested jobs.
|
||||
|
||||
Initially buildmessage was used only for error reporting, but now it is also
|
||||
used for the progress bars. It doesn't hurt the error reporting, it gives the
|
||||
error messages better locality (assuming it is useful).
|
||||
|
||||
## Quick recap:
|
||||
|
||||
- `buildmessage.capture` - the same as a `try-catch` block
|
||||
- `buildmessage.error` - is like throwing an exception (except it doesn't stop there)
|
||||
- `buildmessage.enterJob` - is a concept similar to a stack-frame
|
||||
- `capture.messages()` - get all errors
|
||||
- `job.hasMessages()` - check if there are any errors so far
|
||||
|
||||
|
||||
## Misc
|
||||
|
||||
Helpers for asserting the code structure:
|
||||
|
||||
- `assertInJob`
|
||||
- `assertInCapture`
|
||||
|
||||
A helper to run the user code:
|
||||
|
||||
- `files.runJavascript` - a helper to run the user code
|
||||
- `buildmessage.markBoundary` - a helper that marks the entry point of the user
|
||||
code (like a build plugin), later when an `buildmessage.exception` is called,
|
||||
the buildmessage will remove unnecessary stack-frames from the stack-trace so
|
||||
the error displayed to the user doesn't contain any frames from tool.
|
||||
|
||||
Ex.:
|
||||
|
||||
```
|
||||
var result = null;
|
||||
f = function () { user provided code };
|
||||
try {
|
||||
var markedF = buildmessage.markBoundary(f);
|
||||
result = markedF();
|
||||
} catch (e) {
|
||||
buildmessage.exception(e);
|
||||
// clean up
|
||||
...
|
||||
// pretend nothing happened so we can recover and move on to find other errors
|
||||
result = { name: "dummy" };
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user