-
카테고리
-
세부 분야
백엔드
-
해결 여부
해결됨
createQueryRunner는 undefined속성을 읽을 수 없다
24.04.01 18:55 작성 조회수 85
0
const qr = this.dataSource.createQueryRunner();
ERROR [ExceptionsHandler] Cannot read properties of undefined (reading 'createQueryRunner')
TypeError: Cannot read properties of undefined (reading 'createQueryRunner')
at TransactionInterceptor.intercept (C:\Users\Administrator\Desktop\cf_sns\src\common\interceptor\transaction.interceptor.ts:21:32)
이 에러가 떠서 postman으로 테스트를 진행하지 못하고있습니다.
dataSource도 typeorm에서 import 해서 사용했는데 컨트롤러에서 트랜잭션을 사용할때는 됐다가 인터셉터로 따로 빼서 사용하려고할 때 발생한 오류입니다.
[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - Part 1 NestJS Core
QueryRunner 커스텀 데코레이터 만들기 & Transaction Interceptor 적용하기
강의실 바로가기
답변을 작성해보세요.
0
코드팩토리
지식공유자2024.04.02
안녕하세요!
에러를 번역해보면 createQueryRunner를 undefined에 실행하려고하니 나는 에러네요.
즉, datasource가 undefined입니다.
정상적인 상황이라면 datasource가 undefined가 될 수 없습니다.
this.datasource가 왜 null인지 확인을 하셔야 할 것 같습니다.
interceptor로 따로 빼서 실행하려 할때 나는 에러라면 어떤 코드 변경이 있었는지, 실수한건 없는지 확인 해보셔야겠습니다.
도저히 모르겠다면 문제라고 생각되는 부분들을 더 넓게 캡쳐를 해주셔야합니다. 감사합니다!
감사합니다!
둘리콩콩
질문자2024.04.02
// posts.controller.ts
import {
Body,
Controller,
Post,
UseGuards,
UseInterceptors,
} from '@nestjs/common';
import { QueryRunner as QR } from 'typeorm';
import { TransactionInterceptor } from 'src/common/interceptor/transaction.interceptor';
import { QueryRunner } from 'src/common/decorator/query-runner.decorator';
@Post()
@UseGuards(AccessTokenGuard)
@UseInterceptors(TransactionInterceptor)
async postPosts(
@User('id') userId: number,
@Body() body: CreatePostDto,
@QueryRunner() qr: QR,
) {
const post = await this.postsService.createPost(userId, body, qr);
// throw new InternalServerErrorException('TEST');
for (let i = 0; i < body.images.length; i++) {
await this.postsImagesService.createPostImage(
{
post,
order: i,
path: body.images[i],
type: ImageModelType.POST_IMAGE,
},
qr,
);
}
return this.postsService.getPostById(post.id, qr);
}
// transaction.interceptor.ts
/* eslint-disable prettier/prettier */
import {
CallHandler,
ExecutionContext,
InternalServerErrorException,
NestInterceptor,
} from '@nestjs/common';
import { Observable, catchError, tap } from 'rxjs';
import { DataSource } from 'typeorm';
export class TransactionInterceptor implements NestInterceptor {
constructor(private readonly dataSource: DataSource) {}
async intercept(
context: ExecutionContext,
next: CallHandler<any>,
): Promise<Observable<any>> {
const req = context.switchToHttp().getRequest();
// 트랜잭션과 관련된 모든 쿼리를 담당할
// 쿼리 러너를 생성한다.
const qr = this.dataSource.createQueryRunner();
// 쿼리 러너에 연결한다.
await qr.connect();
// 쿼리 러너에서 트랜잭션을 시작한다.
// 이 시점부터 같은 쿼리러너를 사용하면
// 트랜잭션 안에서 데이터베이스 액션을 실행할 수 있다.
await qr.startTransaction();
req.queryRunner = qr;
return next.handle().pipe(
catchError(async (e) => {
await qr.rollbackTransaction();
await qr.release();
throw new InternalServerErrorException(e.message);
}),
tap(async () => {
await qr.commitTransaction();
await qr.release();
}),
);
}
}
해당 강의에서 사용된 코드 부분입니다.
코드팩토리
지식공유자2024.04.03
dataSource를 직접 생성하고 있지 않으니 IoC로부터 인젝트를 받아야하는데 그러려면 어떻게 해야할까요? (inject 받지 못하니 null이 나오는겁니다)
둘리콩콩
질문자2024.04.03
@Injectable()
이걸 빠뜨렸네용.. 정답을 바로 알려주시지 않고 스스로 찾을 수 있도록 도와주셔서 정말 감사합니다!!
코드팩토리 짱
╰(*°▽°*)╯
답변 1