깊은바다거북
개발 공부 기록
깊은바다거북
전체 방문자
오늘
어제
  • 분류 전체보기 (219)
    • JAVA (9)
    • JavaScript (15)
    • 스파르타코딩클럽 (11)
      • [내일배움단] 웹개발 종합반 개발일지 (5)
      • [내일배움캠프] 프로젝트와 트러블 슈팅 (6)
    • SQL | NoSQL (4)
    • CS 등등 (0)
    • TIL | WIL (173)
    • 기타 에러 해결 (3)
    • 내 살 길 궁리 (4)

인기 글

최근 글

최근 댓글

태그

  • Trie
  • 최대 힙(Max Heap)
  • tree
  • 점화식(Recurrence Relation)
  • POST / GET 요청
  • 프로그래머스
  • Backtracking(백트래킹)
  • 자바스크립트 기초 문법
  • 01. 미니 프로젝트
  • BFS(너비우선탐색)
  • leetcode-cli
  • Preorder Traversal(전위 순회)
  • 시간 복잡도
  • BST(이진 탐색 트리)
  • 혼자 공부하는 자바스크립트
  • Til
  • 코딩테스트 연습문제
  • DFS(깊이우선탐색)
  • Leetcode
  • Linked List
  • 자잘한 에러 해결
  • 자료 구조
  • 트러블 슈팅 Troubleshooting
  • Binary Tree(이진 트리)
  • 재귀 함수
  • Inorder Traversal(중위 순회)
  • 최소 힙(Min Heap)
  • TIT (Today I Troubleshot)
  • TypeScript
  • 팀 프로젝트
hELLO · Designed By 정상우.
깊은바다거북

개발 공부 기록

3/17 금 (<img> 경로 설정 문제) TIL, TIT
TIL | WIL

3/17 금 (<img> 경로 설정 문제) TIL, TIT

2023. 4. 7. 21:56

(최종 프로젝트 진행중)

할 일

  • Date input타입을 서버로 보내기
  • 시작 날짜와 끝 날짜를 requests 테이블에 저장하기
  • ‘모집중|모집완료’ 컬럼을 requests 테이블에 추가하기
  • ‘작성 완료’ 버튼 ajax 연결하기
  • 수정하기 페이지에 기본 글과 함께 불러와놓기
  • 작성자 본인이면 수정하기 및 삭제 버튼이 나타나도록 하기
  • ‘수정 완료’ 버튼 ajax 연결하기
  • ‘모집중’→’모집완료’로 바꿀 방법 생각하기
  • 삭제는 마이페이지에 가서 하도록 할 생각. ?

  • user에게서 받은 집주소로 geoCoder.address…()으로 좌표와 동네명 얻기.
  • ‘처음에 테이블 구조를 단순히 address만 있는 항목으로 만들어서 아직 수정하지 못했다”


※ 이하는 스스로 공부하며 적어둔 노트이며 불확실한 내용이 있을 수 있습니다. 학습용으로 적합하지 않음을 유념해주세요. ※

에러 404 NotFoundException: Cannot GET /request/modify/img/basiclogo.png

발생 상황:

에러 메세지 전문:

NotFoundException: Cannot GET /request/img/basiclogo.png
    at callback (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\@nestjs\core\router\routes-resolver.js:77:19)
    at C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\@nestjs\core\router\router-proxy.js:9:23
    at Layer.handle [as handle_request] (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\index.js:328:13)
    at C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\index.js:286:9
    at Function.process_params (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\index.js:346:12)
    at next (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\index.js:280:10)
    at urlencodedParser (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\body-parser\lib\types\urlencoded.js:91:7)
    at Layer.handle [as handle_request] (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\index.js:328:13)

원인: 경로가 문제였다. 모든 페이지에 걸리는 basicHeader.ejs에 로고 이미지가 이렇게 걸려 있었다:

<a href="/"><img src="../img/basiclogo.png" alt="" ></a>

시도: mainHeader.ejs를 보니 이렇게 걸려있길래(그리고 정상 동작하길래) 똑같이 수정했으나 어째선지 계속 같은 에러를 뱉음:

<a href="/"><img src="img/basiclogo.png" alt="" ></a>

해결: 그래서 이렇게 수정하니 모든 페이지에서 잘 작동함:

<a href="/"><img src="/img/basiclogo.png" alt="" ></a>

(참고할 수 있는, <img> 파일 경로에 대하여: https://www.w3schools.com/html/html_filepaths.asp)

위의 에러와 세트로 나오던 에러가 있었다

[Nest] 34812  - 2023. 03. 17. 오전 10:36:39   ERROR [ExceptionsHandler] C:\Users\USER\Desktop\Sparta\05_project_무인냥품\views\index.ejs:60
    58|
    59|   <% if (components === 'requestList') { %> <%- include('requestList.ejs') %> <% } %>
 >> 60|   <% if (components === 'requestDetail') { %> <%- include('requestDetail.ejs') %> <% } %>
    61|   <% if (components === 'requestPost') { %> <%- include('requestPost.ejs') %> <% } %>
    62|   <% if (components === 'requestModify') { %> <%- include('requestModify.ejs') %> <% } %>
    63|

C:\Users\USER\Desktop\Sparta\05_project_무인냥품\views\requestDetail.ejs:8
    6|
    7|  <div class="cat-cards-container" >
 >> 8|  <% const cats = request.user.cats;
    9|          for (let i = 0; i < cats.length; i++) {
    10|                 const { name, age, gender, neutered, image, character } = cats[i]; %>
    11|

Cannot read properties of undefined (reading 'user')
TypeError: C:\Users\USER\Desktop\Sparta\05_project_무인냥품\views\index.ejs:60
    58|
    59|   <% if (components === 'requestList') { %> <%- include('requestList.ejs') %> <% } %>
 >> 60|   <% if (components === 'requestDetail') { %> <%- include('requestDetail.ejs') %> <% } %>
    61|   <% if (components === 'requestPost') { %> <%- include('requestPost.ejs') %> <% } %>
    62|   <% if (components === 'requestModify') { %> <%- include('requestModify.ejs') %> <% } %>
    63|

C:\Users\USER\Desktop\Sparta\05_project_무인냥품\views\requestDetail.ejs:8
    6|
    7|  <div class="cat-cards-container" >
 >> 8|  <% const cats = request.user.cats;
    9|          for (let i = 0; i < cats.length; i++) {
    10|                 const { name, age, gender, neutered, image, character } = cats[i]; %>
    11|

Cannot read properties of undefined (reading 'user')
    at eval ("C:\\Users\\USER\\Desktop\\Sparta\\05_project_무인냥품\\views\\requestDetail.ejs":12:29)
    at requestDetail (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\ejs\lib\ejs.js:703:17)
    at include (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\ejs\lib\ejs.js:701:39)
    at eval ("C:\\Users\\USER\\Desktop\\Sparta\\05_project_무인냥품\\views\\index.ejs":71:17)
    at index (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\ejs\lib\ejs.js:703:17)
    at tryHandleCache (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\ejs\lib\ejs.js:274:36)
    at View.exports.renderFile [as engine] (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\ejs\lib\ejs.js:491:10)
    at View.render (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\view.js:135:8)
    at tryRender (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\application.js:657:10)
    at Function.render (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\application.js:609:3)
<===========================>
예외발생
예외내용: Cannot GET /request/modify/img/basiclogo.png
예외코드: 404
stack: NotFoundException: Cannot GET /request/modify/img/basiclogo.png
    at callback (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\@nestjs\core\router\routes-resolver.js:77:19)
    at C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\@nestjs\core\router\router-proxy.js:9:23
    at Layer.handle [as handle_request] (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\index.js:328:13)
    at C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\index.js:286:9
    at Function.process_params (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\index.js:346:12)
    at next (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\index.js:280:10)
    at urlencodedParser (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\body-parser\lib\types\urlencoded.js:91:7)
    at Layer.handle [as handle_request] (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\express\lib\router\index.js:328:13)
<===========================>

⇒ 정확하지는 않아도 저 img/basiclogo.png가 네트워크 탭에 계속 ‘대기중’으로 걸려 있어서 덩달아 에러가 났던 듯 하다. img/basiclogo.png 문제를 해결하니 덩달아 해결됐다.

에러 400 BadRequestException: Bad Request Exception

발생 상황: 프론트 ‘품앗이 수정’ 페이지에서 수정 완료 버튼을 클릭해 PATCH http://localhost:3000/requests/52로 요청 API를 날렸으나 동작하지 않음.

에러 메세지 전문:

BadRequestException: Bad Request Exception
    at ValidationPipe.exceptionFactory (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\@nestjs\common\pipes\validation.pipe.js:99:20)
    at ValidationPipe.transform (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\@nestjs\common\pipes\validation.pipe.js:72:30)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at resolveParamValue (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\@nestjs\core\router\router-execution-context.js:147:23)
    at async Promise.all (index 0)
    at pipesFn (C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\@nestjs\core\router\router-execution-context.js:150:13)
    at C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\@nestjs\core\router\router-execution-context.js:37:30
    at C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\@nestjs\core\router\router-execution-context.js:46:28
    at C:\Users\USER\Desktop\Sparta\05_project_무인냥품\node_modules\@nestjs\core\router\router-proxy.js:9:17

시도: Nest.js의 ExceptionFilter로 걸러진 (브라우저 콘솔에 출력될 에러를 서버 콘솔에 출력하는 역할의) 에러 메세지로는 에러를 잡기가 너무 힘들었다.

일단 그래서 main.ts에서 이 글로벌 필터를 제거하고

// main.ts
async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  // app.useGlobalFilters(new HttpExceptionFilter());
	....

브라우저 콘솔창에 출력하도록 한 더 구체적인 메세지를 보니 실마리가 잡혀

// requestModify.ejs
...
$.ajax({
	type: 'PATCH',
	url: `/requests/${id}`,
	contentType: 'application/json; charset=UTF-8',
	data: JSON.stringify({
		reserved_begin_date: startDate,
		reserved_end_date: endDate,
		detail,
	}),
	success: function (response) {
		alert('게시글 수정을 완료하였습니다')
		location.href = '/request/list';
	},
	error: function (response) {
		alert(response.responseText)
		console.log(response);
		console.log(response.responseJSON.message);
	}
})
// => [is_ongoing must be a boolean value]

결국 update-request.dto.ts가 문제라는 것을 깨닫고

// requests/dto/update-request.dto.ts
import { PartialType } from '@nestjs/mapped-types';
import { IsBoolean } from 'class-validator';
import { CreateRequestDto } from './create-request.dto';

export class UpdateRequestDto extends PartialType(CreateRequestDto) {
  //   @IsBoolean()
  //   readonly is_ongoing?: Boolean;
}

이처럼 is_ongoing을 주석처리했더니 됐다.

원인: 내가 알기로 저렇게 ‘있어도 되고 없어도 상관없는’ 변수라고 표시한 것은 이런 에러를 내면 안 되는데 왜 그런지 공부가 필요할 듯 하다. 어쨌든 is_ongoing을 다루는 dto는 update-request-status.dto.ts라고 따로 만들어야겠다.

해결: update-request.dto.ts의 is_ongoing 항목을 주석처리하였다.

4/6 (목) 추가:

나중에 @IsBoolean()이라는 데코레이터만 주석 처리하니 is_ongoing?: boolean 항목 자체는 원래 의도대로 ‘있어도 되고 없어도 상관없는 변수’로 잘 작동했다. 더 알아보니… (추가 예정)

(보던 중: https://stackoverflow.com/questions/55571773/validation-on-optional-parameter-using-class-validator-in-nestjs)

(보던 중: https://docs.nestjs.com/techniques/validation)

(저걸 보기 위해 보던 중: https://docs.nestjs.com/pipes)


Uploaded by N2T

    'TIL | WIL' 카테고리의 다른 글
    • 3/19 일 (Jest로 프론트 동작 테스트하기 연구중) TIL
    • 3/18 토 (localhost에 HTTPS 연결하기와 Geolocation 웹 API 실험) TIL, TIT
    • 3/16 목 (Geolocation API와 Kakao Map으로 위치 인증 간단히 구현하기) TIL
    • 3/15 수 (Kakao Map으로 위치 서비스 만드는 중) TIL
    깊은바다거북
    깊은바다거북

    티스토리툴바