Rules / Suspicious / no-empty-block

no-empty-block

lint/suspicious/no-empty-block
recommended
Same as no-empty-block · Dart Code Metrics

Flags empty blocks ({}).

An empty function, method, loop, or switch-case body is frequently an unfinished implementation or a leftover after code was deleted, and it hides whether the emptiness is deliberate. Fill in the intended behavior, or, if a no-op is genuinely correct, add a comment saying so. Coverage spans functions, class/mixin/enum/extension members (including operators), and switch-case bodies; a block containing only a comment is treated as intentional and left alone. The report lands on the closing brace.

Invalid

example.dartdart
// Test cases for no-empty-block rule
// All violations are marked inline below.

void testEmptyCatchBlock() {
  try {
    riskyOperation();
  } catch (e) {
  }
}

void testEmptyIfBlock() {
  if (condition) {
  }
}

void testEmptyElseBlock() {
  if (condition) {
    print("yes");
  } else {
  }
}

void testEmptyMethodBody() {
  onPressed() {
  }
}

class Widget {
  void onTap() {
  }

  void onLongPress() {
  }
}

void testEmptyForLoop() {
  for (int i = 0; i < 10; i++) {
  }
}

void testEmptyWhileLoop() {
  while (condition) {
  }
}

void testEmptyFinallyBlock() {
  try {
    doSomething();
  } finally {
  }
}

void testMultipleEmptyBlocks() {
  if (a) {
  }
  if (b) {
  }
}

void testEmptyOnBlock(Future<String> future) {
  future.then((_) {
  });
}
Avoid empty blocks — add a comment explaining the intent or remove the block
7 } catch (e) {
8 }
Avoid empty blocks — add a comment explaining the intent or remove the block
12 if (condition) {
13 }
Avoid empty blocks — add a comment explaining the intent or remove the block
19 } else {
20 }
Avoid empty blocks — add a comment explaining the intent or remove the block
24 onPressed() {
25 }
Avoid empty blocks — add a comment explaining the intent or remove the block
29 void onTap() {
30 }
Avoid empty blocks — add a comment explaining the intent or remove the block
32 void onLongPress() {
33 }
Avoid empty blocks — add a comment explaining the intent or remove the block
37 for (int i = 0; i < 10; i++) {
38 }
Avoid empty blocks — add a comment explaining the intent or remove the block
42 while (condition) {
43 }
Avoid empty blocks — add a comment explaining the intent or remove the block
49 } finally {
50 }
Avoid empty blocks — add a comment explaining the intent or remove the block
54 if (a) {
55 }
Avoid empty blocks — add a comment explaining the intent or remove the block
56 if (b) {
57 }
Avoid empty blocks — add a comment explaining the intent or remove the block
61 future.then((_) {
62 });

Valid

example.dartdart
// Good cases for no-empty-block rule
// No violations expected

void testCatchBlockWithHandler() {
  try {
    riskyOperation();
  } catch (e) {
    logger.error('Operation failed: $e');
  }
}

void testCatchBlockWithRethrow() {
  try {
    riskyOperation();
  } catch (e) {
    rethrow;
  }
}

void testIfBlockWithBody() {
  if (condition) {
    print("yes");
  }
}

void testElseBlockWithBody() {
  if (condition) {
    print("yes");
  } else {
    print("no");
  }
}

void testMethodWithBody() {
  onPressed() {
    print("pressed");
  }
}

class Widget {
  void onTap() {
    handleTap();
  }

  void onLongPress() {
    // Allow long press without action for now
    handleLongPress();
  }
}

void testForLoopWithBody() {
  for (int i = 0; i < 10; i++) {
    print(i);
  }
}

void testWhileLoopWithBody() {
  while (condition) {
    process();
    condition = evaluate();
  }
}

void testFinallyBlockWithBody() {
  try {
    doSomething();
  } finally {
    cleanup();
  }
}

void testIfBlockWithComment() {
  if (impossible) {
    // This condition should never be true in practice
    throw AssertionError('Impossible state reached');
  }
}

void testCatchWithComment() {
  try {
    parse();
  } catch (e) {
    // Intentionally swallow parse errors in legacy format
  }
}

void testAsyncCallback(Future<String> future) {
  future.then((value) {
    print('Got: $value');
  });
}

void testEmptyCallbackWithComment(VoidCallback callback) {
  callback = () {
    // No-op callback for testing
  };
}

class ErrorHandler {
  void handleOptional(Error? error) {
    if (error == null) {
      // No error to handle, silent success
      return;
    }
    log(error);
  }
}

How to configure

Set the severity of no-empty-block in your falcon.json:

falcon.jsonjson
{
  "linter": {
    "rules": {
      "suspicious": {
        "no-empty-block": "error"
      }
    }
  }
}