본문 바로가기

node.js (OctoberSkyJs)

[node.js 따라배우기 07] 노드 라이브러리 버전들, 제이드 트릭, 에러페이지 (Node Library Versions, Jade Tricks, Error Pages)

오랜만의 포스팅입니다. 이번 번역은 함께 octoberskyjs 스터디를 진행하고 있는 송형주님(@hyungjoo_)께서 수고해 주셨습니다. 송형주님의 블로그(http://nodejs-kr.org/insidejs/)에는 node.js 모듈들이 소개되고 있으니, 관심있으신 분들은 꼭 한번 살펴보세요. 그리고 무엇보다 연말/연초로 많이 바쁜시기였으셨을텐데 고생많으셨습니다. 고맙습니다. : )

웹 앱(Web App)을 만들어 봅시다” 파트6에 오신걸 환영합니다본 시리즈는 Node를 사용하여 웹 앱을 만들어 보는 튜토리얼(tutorial)입니다이 시리즈는 자기만의 어플리케이션을 만들 때 직면하게 될 모든 부분들을 당신에게 알려줄 것입니다이 튜터리얼들은 lmawa 링크에 있습니다.

Part 1: 소개 (Introduction)

Part 2: 설치와 애플리케이션 뼈대 만들기 (Installation and Skeleton App)

Part 3: RESTful 메소드와 테스트 (RESTful Methods and Testing)

Part 4: 템플릿, 파셜, 그리고 문서 생성과 수정(Templates, Partials, Creating and Editing Documents)

Part 5: 인증과 세션, 접근제어 미들웨어 (Authentication, Sessions, Access Control Middleware)
Part 6: 인터페이스 기본(Interface Basics) 



패키지 버전 (Package Versions)

제가 사용하는 Node와 Mongo 버전을 포함한 Nodepad README 업데이트 했습니다. 그 파일에는 제가 사용한 다른 패키지들의 버전들도 포함되어 있습니다. 만약 코드 실행에 문제가 있다면 그것은 이를 해결하는데 도움이 될 것입니다. 저는 Nodepad 코드를 Mac OS와 Debian에서 테스트했습니다.

여러분이 코드를 수정할 때마다 (Jade 템플릿 코드 제외) Node를 재실행 실켜야 하는 것 또한 기억해주세요.

우리는 패키지 설치를 위해서 npm을 이용했고, 특정 버전의 패키지가 설치될 수 있도록 경로명을 설정할 것입니다. 이를 위해서는 다음과 같이 실행하면 됩니다. (역자주-현재 express 최신 버전은 3.0 알파 버전까지 나와 있다.)

npm install express@1.0.0

설치된 모듈을 사용하기 위해선 다음과 같이 입력합니다.

var express = require('express@1.0.0');

node 명령을 실행 후, 커맨드라인에서 다음과 같이 입력해서 모듈 동작을 확인할 수 있습니다.

> express = require('express@1.0.0')
{ version: '1.0.0'
, Server: { [Function: Server] parseQueryString: [Function] }
, createServer: [Function]
}


Jade 트릭(Jade Tricks)

이전 튜터리얼에서는 Jade를 이용했을 때는 모든 속성을 하드 코딩했습니다. Jade 코딩 시에 클래스와 ID를 셀렉터를 이용해서 간단히 입력하면, 많은 수고를 덜 수 있습니다.

div#left.outline-view
  div#DocumentTitles
    ul#document-list
      - for (var d in documents)
        li
          a(id='document-title-' + documents[d].id, href='/documents/' + documents[d].id)
            =documents[d].title

div#left.outline-view는 ID 셀렉터와 class명이 결합한 것임을 기억하세요.

Jade의 디폴트 태그는 div이므로, 앞의 예제는 다음과 같이 줄일 수 있습니다.

#left.outline-view
  #DocumentTitles
    ul#document-list
      - for (var d in documents)
        li
          a(id='document-title-' + documents[d].id, href='/documents/' + documents[d].id)
            =documents[d].title


에러 페이지 (Error Pages)

Express에서는  app.error 를 통해 자체 에러 핸들러를 정의할 수 있습니다. 

// 에러 핸들링
function NotFound(msg) {
  this.name = 'NotFound';
  Error.call(this, msg);
  Error.captureStackTrace(this, arguments.callee);
}

sys.inherits(NotFound, Error);

// 이 메서드의 결과로 500.jade가 렌더링 될 것이다.
app.get('/bad', function(req, res) {
  unknownMethod();
});

app.error(function(err, req, res, next) {
  if (err instanceof NotFound) {
    res.render('404.jade', { status: 404 });
  } else {
    next(err);
  }
});

app.error(function(err, req, res) {
  res.render('500.jade', {
    status: 500,
    locals: {
      error: err
    } 
  });
});

에러 핸들러는 error, req, res, next 이렇게 4개의 인자를 갖습니다. next 메서드는 error 인자를 다음 에러 핸들러로 넘기는데 사용됩니다. 위 예제에서 404 에러 핸들러는 NotFound 이외의 에러들은 다른 에러 핸들러로 넘깁니다. 그리고 다른 모든 에러들은 두번째 에러 핸들러로 전달되며, 이들은 500 에러로 여깁니다.

브라우저에서 /bad 주소를 입력하면, 우리가 만든 500 에러 페이지가 보여질 것입니다. render 메서드 호출시, 옵션 인자로 HTTP 상태 코드를 넘긴 것을 기억하세요. 여기서 status 코드를 넘기지 않으면 404나 500 에러 대신에 200 상태 코드가 반환됩니다. 
 

Mongoose 코드 내부에서 에러 처리하기 (Error Handling within Mongoose Code)

next 메서드는 우리가 작성한 애플리케이션 내부의 모든HTTP 처리 메서드(역자주. 원문은 HTTP verb method라고 되어 있음)에서 이용 가능합니다. 우리는 이 메서드를 자체 404 페이지를 렌더링 하는 데 사용합니다.

app.get('/documents/:id.:format?/edit', loadUser, function(req, res, next) {
  Document.findById(req.params.id, function(d) {
    if (!d) return next(new NotFound('Document not found'));
    // Else render the template...

위 코드가 Mongoose 코드 내부에서 에러를 처리하기 위해 제가 찾아낸 가장 쉬운 패턴입니다. Mongoose 콜백 함수내에서 간단히 throw new NotFound를 사용하면  Express의 에러 핸들러를 트리거 하는 대신에 애플리케이션을 중단시킬 수 있습니다.
 

결론 (Conclusion)

Node 애플리케이션을 배포할 때 패키지 버전에 대해 정확히 기록하는 것은 중요합니다. 많은 주요 패키지들이 여전히 활발히 개발 중에 있어서 배포가 쉽지 않기 때문입니다.

Express는 템플릿과 함께 자체 에러 핸들러를 쉽게 생성할 수 있게 해줍니다. 콜백 함수 내에서 HTTP 상태 코드를 정확하게 넘기고 next(exception)을 사용해야 하는 점을 꼭 기억하세요.

이 튜터리얼을 적용한 Nodepad 버전은 commit 929f564에 있습니다.