I recently faced an unexpected error while working on two different projects that pointed to the same API backend server built with Nest.js. One project was a Next.js app designed for mobile users, while the other was a Node.js app for handling Arduino hardware.
Everything was running smoothly with the mobile user service until the following error popped up for the Arduino integration:
- BadRequestException: Bad Request Exception
- ~/node_modules/@nestjs/common/pipes/validation.pipe.js in ValidationPipe.transform at line 74:30
- ~/node_modules/@nestjs/common/pipes/validation.pipe.js in ValidationPipe.exceptionFactory at line 101:20
At first glance, I had no idea what could be causing this error since everything worked fine for the mobile service. Both apps were using the same backend, so why was only the Arduino app encountering this?
Digging Deeper
I started investigating, trying to determine what might be wrong. Since the error was triggered in Nest.js, I focused on the ValidationPipe as highlighted in the error stack trace. The ValidationPipe is commonly used in Nest.js to validate incoming data, ensuring it matches the defined Data Transfer Objects (DTOs).
The first step was to check the logs and console output from both my Next.js app and the Node.js app for Arduino. Interestingly, while the mobile service worked perfectly, the Arduino integration was throwing the BadRequestException error whenever it attempted to communicate with the API.
I realized that the issue likely stemmed from a data mismatch — meaning the data coming from Arduino did not align with what was expected by the DTO in my Nest.js backend.
The Root Cause: Class-Validator Mismatch
The problem boiled down to the class-validator library used by Nest.js. This library validates incoming data against the DTOs defined in the Nest.js project. If the data doesn’t match, it throws a BadRequestException.
Upon closer inspection, I saw that the values sent from the Arduino were slightly off compared to what I had defined in the DTO. For example, I expected strings where numbers were being sent, or I had required fields that were missing entirely from the Arduino request.
The Fix
After identifying the mismatches, I modified the return values from the Arduino setup to ensure that they followed the structure expected by the Nest.js DTO. This meant ensuring that every piece of data sent from Arduino was properly formatted and matched the required types.
Here’s a simplified example of how I fixed the issue:
Original Arduino return (causing validation error):
{
"deviceId": 12345,
"status": true
}
Expected by Nest.js DTO (after fix):
{
"deviceId": "12345",
"status": "active"
}
Once I corrected the return values, everything started working flawlessly, and the BadRequestException error was gone!
Lessons Learned
This experience reminded me of a few valuable lessons:
- Always Validate Your Data: Whether it’s coming from a mobile app, hardware device, or another service, ensuring that the data aligns with what your API expects can prevent many headaches.
- Leverage Error Messages: The error stack trace was a helpful guide to locate the exact point of failure. The ValidationPipe in Nest.js made it clear that the issue was related to how data was being validated.
- Consistency is Key: When working with multiple platforms (mobile, hardware, etc.), make sure that data structures are consistent across the board.
- Testing is Essential: It’s always a good idea to test different use cases, even when working with systems like Arduino that seem unrelated to your other services.
Conclusion
The error might have seemed mysterious at first, but once I figured out the source, it became clear that the data mismatch was causing the problem. By ensuring that the Arduino data conformed to the required DTO structure, I was able to get everything running smoothly.
In the end, it was just another reminder that even the smallest details — like data types — can make or break your project.