@Catch(HttpExceptioin) 데코레이터는 필요한 메타데이터를 Exception Filter에 바인딩하여 Nest에게 이 특정 필터가 위의 내장 HttpException 유형의 예외를 찾고 있으며, 다른 예외는 없음을 알려준다. 또한 쉼표로 구분지어 여러 유형의 예외에 대한 필터를 한 번에 설정할 수 있다.
모든 Custom Exception Filter는 일반 ExceptionFilter interface를 구현해야 한다. 위 Custom Filter에 구현된 catch 메서드를 제공해야 한다는 뜻이다.
또한 @nestjs/platform-fastfy를 사용하는 경우, response.json() 대신 response.send()를 사용할 수 있다.
필터는, @UseFilters 데코레이터를 이용하여 적용시켜주면 되는데, 이 때 원하는 엔드포인트에 사용할 수 있다.
@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
throw new ForbiddenException();
}
@Controller('user')
@UseFilters(HttpExceptionFilter)
export class UserController
애플리케이션 전역에서 작용하는 Filter로 설정하기 위해서는 main.ts 파일 안에서 다음과 같이 useGlobalFilters() 메서드를 사용한다.
# docker group을 생성 (이미 있었음)
$ sudo groupadd docker
# 현재 유저(ubuntu)를 docker group에 추가
$ sudo usermod -aG docker $USER
# 그룹 변경 명령어. 혹은 도커 로그아웃, 로그인 진행
$ newgrp docker
잘 삭제 되었다.
참고로 위에서 GPT에게 받은 dangling된 이미지를 지우는 명령어는 prune으로 족하다고 한다.
$ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Deleted Images:
deleted: sha256:f7c5c7a3bbf08fbaefe57672bb3d7eb0f6c4a60fc2bd303ede54aacf29031ad3
.....
deleted: sha256:d7d5f3f6791131da7f70f52b086f0acec373e5c6f0d66d7fbcd5276b47468e28
Total reclaimed space: 17.29MB
나는 예제에다 alpine을 추가하여 사용했는데, 알파인은 클라우드 환경을 고려한 가벼운 리눅스 이미지다.
실습을 진행할 것이기 때문에 알파인으로 사용하였다.
DockerFile
# Base image
FROM node:18-alpine
# Create app directory
WORKDIR /usr/src/app
# A wildcard is used to ensure both package.json AND package-lock.json are copied
COPY package*.json ./
# Install app dependencies
RUN npm install
# Bundle app source
COPY . .
# Creates a "dist" folder with the production build
RUN npm run build
# Start the server using the production build
CMD [ "node", "dist/main.js" ]
es6에서 포함된 기능중 하나는, 변수 선언에 사용할 수 있는 키워드인 let, const의 추가였다.
혹여 단순 using에 대한 정보만을 얻고자한다면, 스크롤을 많이 내려야 할 것 같다.
var의 문제점
기존의 var 변수가 함수 외부에서 선언될 때의 범위는 전역이고, 함수 내에서 선언될 때는 함수 범위 내로 지정된다.
var hi = "hey hi";
function test() {
var hello = "hello";
}
//error: hello is not found
console.log(hello);
hello는 test() 함수 밖에서 사용할 수 없기 때문에 에러가 발생할 것이다.
또한 var 변수는 재선언이 가능하다.
var test = "test code"
var test = "test test"
var test2 = "test2 code"
test2 = "test2 test2"
var는 호이스팅 때문에 다음과 같은 코드를 작성하면 test is undefined를 발생시킨다.
console.log(test)
var test = "test"
//** test is undefined!!!!
//real action (Hoisting)
var test
console.log(test)
test = "test"
var의 이와같은 특징들을 활용하여 아래 코드를 살펴보자.
얼핏보면 괜찮은 var을 활용한 코드를 작성했다고 생각할 수 있다.
var test = "test"
var test2 = 10
if (test > 9) {
var test = "hi hello"
}
console.log(test)
// >> "hi hello"
위 코드는 if문이 true기 때문에 test 변수는 재정의된다. 의도적으로 재정의한다면 괜찮겠지만, test 변수가 이미 정의되어 있다는 사실을 인식하지 못하는 경우에는 문제가 될 수 있다. 코드의 다른 부분에서 test 변수를 사용했다면 다른 출력값에 당황하게 될 수 있다.
요약해보면, var은 블록 스코프를 지원하지 않고, 재선언이 가능한 특성을 갖고 있다. 또한 호이스팅이 발생하기 때문에 가독성이 저하되고, 변수 선언 이전에 변수를 사용해도 오류가 발생하지 않는 등 많은 문제를 발생시킨다. 그리하여 const, let이 등장하게 되었다.
let
let으로 선언된 변수는 해당 블록 내에서만 사용이 가능하다.
let test = 'test'
let test2 = 10
if (test2 > 9) {
let result = 'let is powerful'
console.log(result) // 'let is powerful'
}
console.log(result) // result is not defined
result 변수가 정의된 블록 외부에서 해당 변수를 사용하면 에러가 발생된다.
또한 let은 업데이트는 가능하지만, 재선언은 불가능하다.
let test = 'test'
test = 'not test, its real'
let test = 'test'
let test = 'not test, its real'
// error: Identifier 'test' has already been declared
하지만, 다른 범위 내에서 재정의된다면 에러는 발생하지 않는다. 서로 다른범위를 가지므로 서로 다른 변수로 취급되기 때문이다.
let test = 'test'
if (true) {
let test = 'its real test'
}
console.log(test) // 'its real test'
이처럼 let을 사용한다면, 변수가 범위 내에서만 존재하기 때문에, 이전에 이미 사용한 변수 명에 대해 더이상 신경쓰지 않아도 된다. 또한 범위 내에서 동일한 변수를 두 번 이상 선언할 수 없기 때문에 var의 문제가 발생하지 않는다.
또한 let의 경우, 호이스팅 시 초기화가 되지 않는다. 즉 호이스팅으로 선언은 되었지만 초기화가 되지 않았으므로 undefined의 값을 가지지 못한다. 그리하여 Reference Error를 뱉어낸다. test가 초기화되기 전에 사용되었기 때문이다.
console.log(test)
let test = "test"
//real action
let test
console.log(test) // Reference Error
test = "test"
여기서 계속 말하는 선언과 초기화는 다음 정의를 가진다. 선언(Declaration) : 스코프와 변수 객체 생성. 스코프가 변수 객체를 참조 초기화(Initialization) : 변수 객체 값을 위한 공간을 메모리에 할당된다 (undefined)
const
단어의 뜻에서도 알 수 있듯이 상수값을 유지하는 변수이다. 당연히 업데이트도, 재선언도 불가능하다.
const 또한 let처럼 선언된 블록 범위에서만 접근이 가능하다.
const test = 'i am constants'
test = 'change' //error: Assignment to constant variable
const test = 'i am constants'
const test = 'change' // error: Identifier 'test' has already been declared