Silencing Errors: Introduction
Errors reported by the Hack typechecker can be silenced with
HH_FIXME
and HH_IGNORE_ERROR
comments.
Silencing Errors
/* HH_FIXME[4110] Your explanation here. */
takes_int("foo");
To silence an error, place a comment on the immediately previous
line. The comment must use the /*
syntax.
This syntax only affects error reporting. It does not change types, so the typechecker will keep checking the rest of the file as before.
This syntax also has no runtime effect. The runtime will do its best with badly typed code, but it may produce an error immediately, produce an error later in the program, or coerce values to an unwanted type.
The behavior of badly typed code may change between HHVM releases. This will usually be noted in the changelog.
HH_FIXME
versus HH_IGNORE_ERROR
Both HH_FIXME
and HH_IGNORE_ERROR
have the same effect: they
suppress an error.
/* HH_FIXME[4110] An example fixme. */
takes_int("foo");
/* HH_IGNORE_ERROR[4110] This is equivalent to the HH_FIXME above. */
takes_int("foo");
You should generally use HH_FIXME
. HH_IGNORE_ERROR
is intended to
signal to the reader that the type checker is wrong and you are
deliberately suppressing the error. This should be very rare.
Error Codes
Every Hack error has an associated error code. These are stable across Hack releases, and new errors always have new error codes.
Hack will ignore error suppression comments that have no effect, to help migration to newer Hack versions.
Error codes 1000 - 1999 are used for parsing errors. Whilst it is possible to silence these, the runtime usually cannot run this code at all.
Error codes 2000 - 3999 are used for naming errors. This includes references to nonexistent names, as well as well-formedness checks that don't require type information.
Error codes 4000 - 4999 are used for typing errors.
Configuring Error Suppression
Once you have removed all the occurrences of a specific error code, you can ensure that no new errors are added.
You can use the ignored_fixme_codes
option in .hhconfig
to forbid
suppression of a specific error code.
ignored_fixme_codes = 1002, 4110
This forbids /* HH_FIXME[4110] ... */
.
.hhconfig
also supports disallowed_decl_fixmes
, which forbids
error suppression of specific error codes on declarations (types,
class properties etc).
disallowed_decl_fixmes = 1002, 4110
This forbids /* HH_FIXME[4110] ... */
outside of function and method
bodies.
Partial mode files have fewer checks. You can opt-in to specific
strict mode checks in partial files by using the error code in
error_codes_treated_strictly
in .hhconfig
.
error_codes_treated_strictly = 1002, 2045, 2055, 2060, 4005
Best Practices
Great Hack code has no error suppressing comments, and only uses strict mode.
Suppressing errors in one place can lead to runtime errors in other places.
function takes_int(int $_): void {}
function return_ints_lie(): vec<int> {
/* HH_FIXME[4110] The type error is here. */
return vec["foo"];
}
<<__EntryPoint>>
function oh_no(): void {
$items = return_ints_lie();
takes_int($items[0]); // But the exception is here!
}
Good Hack code has no error suppression comments on its declarations. Suppressing errors in declarations can hide a large number of issues elsewhere.
function takes_int(int $_): void {}
function takes_float(float $_): void {}
/* HH_FIXME[4030] Missing a return type. */
function returns_something() {
return "";
}
function oh_no(): void {
// This is wrong.
takes_int(returns_something());
// This is wrong too!
takes_float(returns_something());
}
When you use error suppression, make sure you specify a reason. Try to keep your comments to small expressions, because the comment applies to the entire next line.
/* HH_FIXME[4110] Bad: this can apply to both function calls! */
$result = foo(bar("stuff"));
/* HH_FIXME[4110] Better: we will spot errors when calling bar. */
$x = foo("stuff");
$result = bar($x);