I have a nestjs application in which I created a pipe to check if the value is a valid URL. If the URL is invalid, throw an error. This is used in a controller to save an item into the database.
I just realized the pipe would throw 500 with Internal Server Error, I had to check the server log to see if it's actually from the pipe.
I wonder if there's a way that we can have an HTTP response directly with the message?
The pipe code I have is...
import { BadRequestException, Injectable, PipeTransform } from '@nestjs/common';
@Injectable()
export class ValidUrlPipe implements PipeTransform {
transform(website: string) {
if (website === '') return website;
const validProtocols = ['http:', 'https:'];
const { protocol } = new URL(website);
if (validProtocols.includes(protocol)) {
return website;
}
throw new BadRequestException(`invalid website value: ${website}`);
}
}
the controller using the pipe looks like
@Post()
create(
@Body('website', ValidUrlPipe) website: string,
@Body() createTvDto: CreateTvDto,
@CurrentUser() user: User,
) {
return this.televisionsService.create(user._id, createTvDto);
}
Thank you so much in advance for any suggestions/solutions.
EDIT: I added an image of the error thrown by using Postman to call the endpoint
Dora, let me help you with the actual solution:
import { BadRequestException, Injectable, PipeTransform } from '@nestjs/common';
@Injectable()
export class ValidUrlPipe implements PipeTransform {
transform(website: string) {
if (website === '') return website;
const validProtocols = ['http:', 'https:'];
try {
const { protocol } = new URL(website);
if (validProtocols.includes(protocol)) {
return website;
}
} catch (error) {
// Maybe add another bit of logging here for your own records if it is of interest?
throw new BadRequestException(`invalid website value: ${website}`);
}
}
}
For those of you privileged with Node 20:
Instead of wrapping it all in a try/catch, you could use the static method URL.canParse().
Implemented for your pipe:
import { BadRequestException, Injectable, PipeTransform } from '@nestjs/common';
@Injectable()
export class ValidUrlPipe implements PipeTransform {
transform(website: string) {
if (website === '') return website;
const validProtocols = ['http:', 'https:'];
if (URL.canParse(website)) {
// URL.canParse(...) returns a boolean if the url is valid or not
const { protocol } = new URL(website);
if (validProtocols.includes(protocol)) {
return website;
}
}
throw new BadRequestException(`invalid website value: ${website}`);
}
}