- Lab
- Core Tech

Guided: Error Handling and Testing in NestJS
In this CodeLab, you'll enhance a NestJS application by implementing global error handling strategies and creating a custom exception filter to improve and standardize error responses. Additionally, you'll develop both unit and end-to-end tests covering various aspects of the application to ensure overall reliability for this application.

Path Info
Table of Contents
-
Challenge
Introduction
Introduction
Error handling involves anticipating, capturing, and managing unexpected conditions in an application to ensure it remains stable, provides meaningful feedback, and facilitates debugging. Testing is the practice of systematically verifying that software behaves as expected through techniques like unit, integration, and end-to-end testing.
Both of these concepts can go hand in hand to help catch bugs early and ensure long-term reliability.
Error Handling and Testing in NestJS
NestJS addresses error handling through its built-in and custom exception filters, ensuring consistent HTTP responses and logging of errors. This modular approach lets developers tailor error handling for different scopes across the application.
For testing, NestJS leverages Jest as its default testing framework. Its dependency injection and modular architecture facilitate the isolation of components, allowing developers to simulate real-world scenarios and verify application behavior.
Working with the Application
In this lab, you will incorporate both custom and built-in exceptions for this NestJS application. Afterwards, you will look into writing unit and end-to-end tests using tools provided by the NestJS framework. As you progress through the lab, you can interact with it when running the application through the Swagger interface, which can be found in the Simple Web Browser tab after you have run the application.
You can run the application in the Run Server terminal with either
npm run start
ornpm run start:dev
. Thestart:dev
version will set it in watch mode, which will dynamically refresh whenever you make any changes to files. After running the application, make sure to addapi
to the url in the simple browser to access the Swagger interface.There is also a
solution
directory for you to check your implementations at any time. -
Challenge
Built-in Exceptions
NestJS comes with a global exception filter that is meant to catch errors and exceptions that occur. The framework comes with many built-in exceptions that correspond to the standard HTTP error responses.
Review the
item.service.ts
Open the
src/item/item.service.ts
file. Inside this file, you will find a completed service for theItem
resource. For this step, you will need to modify thefindOne()
andremove()
methods to throw a specific exception to handle certain inputs.
Throwing a built-in Exception
Throwing a built-in HTTP exception in NestJS is as simple as the following:
throw new HTTPExceptionType('insert error message')
Alternatively, you can also utilize the optional
options
object parameter in an exception to provide more detail for a caught exception such as:throw new HTTPExceptionType('insert error message', { cause: new Error(), description: 'insert more details', })
Inside the
findOne()
method, you will need to throw two specific errors. Similarly tofindOne()
, you will need to add a conditional to throw a built-inNotFoundException
withinremove()
. ## ConclusionYou have successfully implemented and utilized the global exception filter that NestJS provides through its built-in exceptions. Next, you will look into custom exception filters for more specialized uses.
-
Challenge
Custom Exception Filters
While the built-in exceptions provided by NestJS can handle most error handling needs, there may be times when you need full granular control or a more specific exception filter. Enhanced exception logging beyond simple error messages is one such example.
Review
LoggingExceptionFilter
The custom exception filter you will be implementing is the
LoggingExceptionFilter
class located insrc/filters/LoggingExceptionFilter.filter.ts
. Most of the business logic for the filter has already been done, but you will need to add some finishing touches and register it under Nest's dependency injection system.Custom Exception Filters can be designed to apply to different scopes of an application, whether it's specific to a single method, specific to a certain controller, or even bound globally across the entire application.
The
@Catch()
decorator provided by NestJS allows you to mark a class to pick up certain exceptions. This can hold more than just one exception type to catch as long as they are comma-separated. For this filter, you will make it a catch-all filter. To obtain control over the request-response flow for your exception filter, you will need to hook into these objects using an execution context such asArgumentsHost
for the underlying platform. By default, most NestJS applications(including this one) utilize Express, so you will be hooking into theRequest
andResponse
objects from Express. Now that you've hooked into the underlyingRequest
object, thecatch()
method can now utilize them to retrieve information on caught exceptions and formulate a more in-depth report for them. Now you just need to return this information through theResponse
object. Now that you've completed the custom exception filter, you will need to register it for the NestJS framework to recognize it. As mentioned previously, this filter is meant to be a catch-all filter that is applied globally rather than to a specific controller or method. Head to theapp.module.ts
file to bind it. ## ConclusionWith this, you've successfully setup a custom catch-all exception filter that provides a more informative overview for all HTTP and unrecognized exceptions. Next, you will dive into some unit and end-to-end testing in NestJS.
-
Challenge
Testing
Testing in NestJS is done by default through Jest, so those who are familiar with Jest already understand almost everything there is to it. In NestJS, tests are typically either unit tests or end-to-end(e2e) tests, which are conducted through the usage of the
supertest
library to simulate requests.One other thing that NestJS provides specifically for testing is the
Test
andTestingModule
classes, which can be utilized in your test files to mock your NestJS application while supporting dependency injection.
Unit and End-to-End Test Files
Per NestJS convention you will usually find your unit test files co-located with the files they are related to, whereas e2e tests will usually be found in the
test
directory. For this lab, you will be working on theitem.service.spec.ts
unit test in thesrc/item
directory to testfindOne()
. Thedelete-remove.e2e-spec.ts
e2e test withintest
will be used to testremove()
.First, take a look at
item.service.spec.ts
.
The
BeforeAll()
fixture runs before all test cases and instantiates aTestingModule
. You can inject theItemService
as a dependency into thisTestingModule
which will make it available for testing. This is already done for you through boilerplate generation, but you will need to assign theItemService
to a variable. The first test case marked by the firstit()
function will test whether yourfindOne()
method properly returns aBadRequestException
when provided an invalid input. The next test case needs to test that yourfindOne()
method throws aNotFoundException
when given a certain input and that the error response matches the expected error response. The last test case in your unit test needs to test that thefindOne()
method returns the correctItem
. -
Challenge
Testing(Cont.)
Now you will need to move on to the e2e test for
remove()
. Take a look atdelete-remove.e2e-spec.ts
. This e2e test looks just like your unit test, but this time it includes anINestApplication
calledapp
. This variable will be used to mock your full application when testing your endpoint attached toremove()
.Before you can start working on your test case, you will need to instantiate this app using the
TestingModule
. When performing e2e testing, it's also best practice to close yourapp
instance after all test cases have been run. Lastly, you will complete the test case that involves using theremove()
method tied to the DELETE endpoint. A good portion of the test case has already been provided to you, all that's left for you to add is to make simulatedrequest
calls from thesupertest
library. ## ConclusionIf you've made it here then you have successfully implemented built-in exceptions along with a custom exception filter for your NestJS application. Furthermore, you've also managed to witness and work with Nest's
Test
andTestingModule
classes to facilitate testing for the application.Great job on completing this lab!
What's a lab?
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.