Blog Home

Reduce Nesting, Reduce Complexity

2017-06-15

Deeply nested code is error-prone and hurts readability.

Bad

Response response = server.Call(request);

if (response.GetStatus() == Status::kOk) {
  if (!IsAuthorized(response.GetUser())) {
    if (response.GetEnc() == "utf-8") {
      std::vector<Row> rows = response.GetRows();
      if (!rows.empty()) {
        avg = std::accumulate(rows.begin(), rows.end(), 0, ParseRow) / 
              rows.size();
        return avg;
      } else {
      throw EmptyException();
    } else {
      throw AuthException('unauthorized');
    }
  } else {
    throw ValueException('wrong encoding');
  }
} else {
  throw RpcException(response.GetStatus());
}

The code above could be refactored to use guard clauses.

Good

Response response = server.Call(request);

if (response.GetStatus() != Status::kOk) {
  throw RpcException(response.GetStatus());
}

if (!IsAuthorized(response.GetUser())) {
  throw ValueException('wrong encoding');
}

if (response.GetEnc() != "utf-8") {
  throw AuthException('unauthorized');
}

std::vector<Row> rows = response.GetRows();
if (rows.empty()) {
  throw EmptyException();
}

avg = std::accumulate(rows.begin(), rows.end(), 0, ParseRow) / rows.size();
return avg;

Can you spot the bug now?