In a previous article, I mentioned that Windsurf and Cursor have certain code review capabilities, which can not only detect code style issues but also identify logical errors in the code. This is extremely valuable in practice, as it can fully utilize the Copilot capabilities of large models while avoiding trust issues with tool-generated code.
Previous validations required the tool to conduct a code review on a single class, with the code implementation limited to one class. However, in actual work, the code implementation for the same requirement is often distributed across different methods and even different projects. For example, typical CRUD operations may be spread across multiple methods, and the user ordering process may involve multiple microservices for users, orders, and payments.
So, can the tool correctly identify deeper logical defects that involve multiple method implementations? Let’s conduct a validation.
1. In the product information reading interface, it first reads the cached information in Redis; if it misses, it reads the database information.
2. In the product information updating interface, it only updates the product information in the database.
3. When there is a product with ProductID 1 in Redis, execute the update operation for that product, then execute the read operation.
4. At this time, the product information read by the user should be inconsistent with that in the database.
1. IDE: Windsurf Version: 1.2.1
2. Model: Claude 3.5 Sonnet
3. Code Framework: Spring Boot 3.2.0
4. Database: SQLite 3.43.2
CREATE TABLE "product" ( "id" integer NOT NULL, "price" integer, "productname" varchar(255), "version" integer, PRIMARY KEY("id"));
This is a typical CRUD code structure implemented based on the Spring Boot framework. The interface implementation is in the ProductController class, with the interface for accessing a single product’s information being getProduct and the update interface being updateProduct. The logical methods are implemented in the ProductService class, which does not include Redis operations in the update product information interface. The code is as follows:
@Transactional(isolation = Isolation.REPEATABLE_READ) public Product saveProduct(Product product) { try { // Save to database Product savedProduct = productRepository.save(product); return savedProduct; } catch (Exception e) { logger.error("Error saving product: {}", e.getMessage(), e); throw e; } }
When reading, it will prioritize reading from Redis, as shown in the code below:
@Transactional(readOnly = true) public Optional<product> getProductById(Long id) { String key = REDIS_PRODUCT_KEY_PREFIX + id; logger.debug("Looking up product with id: {}", id); // Try to get from Redis first Object cachedValue = valueOperations.get(key); if (cachedValue != null) { logger.debug("Found cached value of type: {}", cachedValue.getClass().getName()); if (cachedValue instanceof Product) { logger.info("Cache hit for product id: {}", id); return Optional.of((Product) cachedValue); } else { logger.warn("Cached value is not a Product instance: {}", cachedValue); } } logger.info("Cache miss for product id: {}, fetching from database", id); // If not in Redis, get from database Optional<product> productOpt = productRepository.findById(id); logger.debug("Database lookup result: {}", productOpt); // Cache the result if (productOpt.isPresent()) { logger.info("Caching product id: {} in Redis", id); Product product = productOpt.get(); logger.debug("Product to cache: {}", product); valueOperations.set(key, product, CACHE_DURATION, TimeUnit.HOURS); } else { logger.info("Product not found in database with id: {}", id); } return productOpt; }</product></product>
This is a not-so-obvious logical error. If the read interface is developed by person A and the write interface is developed by person B, B might overlook Redis writing due to a lack of understanding of the architecture. During the unit testing phase, if the assert conditions are not rigorous enough, this defect may also be overlooked.
1. Checking ProductController
Following the logic of manual code review, we should start code inspection from the top level of the code implementation. So, I asked Windsurf to conduct a code review on the ProductController code.
The tool did not detect this logical error. Although it provided some reasonable modification suggestions, it did not identify this logical error.
1. Dependency injection issues exist with duplicate dependencies: productRepository is already used in ProductService, and the Controller should not directly depend on the Repository. Suggestion: Remove productRepository dependency and only access data through the Service layer. 2. Input validation lacks validation for input parameters. Suggestion: Add @Valid annotation and corresponding validation rules. Validate price with @Min(0) and productname with @NotBlank. 3. Error handling lacks global exception handling. Suggestion: Create @ControllerAdvice to handle exceptions uniformly and add business exception classes (e.g., ProductNotFoundException) to return more detailed error information. 4. API documentation lacks API documentation annotations. Suggestion: Add Swagger/OpenAPI annotations to document the API. 5. Version control lacks API version control. Suggestion: Add version numbers in the URL, such as /api/v1/products. 6. Response encapsulation directly returns entity objects, which may expose unnecessary information. Suggestion: Create DTO objects to encapsulate response data.
2. Checking ProductService
Since the defect was not detected at the Controller level, I asked Windsurf to check the ProductService layer code.
Although the tool provided reasonable suggestions regarding cache usage, it still did not detect this defect.
Complete suggested improvements: 1. Add cache warming mechanism. 2. Implement distributed locking to prevent cache breakdown. 3. Add null value caching to prevent cache penetration. 4. Add cache time randomization to prevent cache avalanche. 5. Delete cache instead of updating it during update operations. 6. Add cache handling for batch operations. 7. Increase cache statistics and monitoring.
At this point, I realized I had fallen into a thinking trap; I assumed the tool was just an assistant and could not work independently while expecting it to handle practical issues like a human. A complete code review should start from the requirements, so I directly asked Windsurf to check the CRUD functionality implementation based on the requirements.
This time, Windsurf performed a relational check between the controller and service codes, successfully detecting this logical error.
AI-assisted coding tools have high practical value in code review. Windsurf, combined with Claude 3.5 Sonnet, has a certain ability to identify potential complex code defects, providing greater value for this capability. When utilizing large models for code review, it is recommended to clear contextual association information and start the model review from the requirements to achieve more accurate review results.