반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

런타임 에러 처리하기

2013. 3. 7. 22:29 | Posted by 솔웅


반응형
Posted on . Written by



안드로이드용으로 빌드하시는 분들은 에러를 report 하는 방법이 바뀐것을 공지해 드렸었습니다. 이 기능은 안드로이드쪽에 먼저 작업이 됐는데요 그 이유는 custom 안드로이드 퍼미션 기능을 implement 하는 부분을 수정하면서 런타임 에러를 처리하는 기능이 개선될 필요가 있었기 때문입니다.

이제 다른 플랫폼에도 이 기능이 지원돼야 겠죠. iOS 와 시뮬레이터 등에도 런타임에러를 캐치하고 처리하는 기능이 지원될 차례입니다. 에러를 trap 해서 런타임 에러 팝업을 보여줄지 안 보여줄 지 하는  기능도 지원되게 됩니다. 이 기능을 통해서 런타임 에러를 fix 하는 것은 아니지만 그 런타임 에러를 감출수는 있을 겁니다.

런타임 에러를 처리하는 예제입니다.

local function myUnhandledErrorListener( event )

    local iHandledTheError = true

    if iHandledTheError then
        print( "Handling the unhandled error", event.errorMessage )
    else
        print( "Not handling the unhandled error", event.errorMessage )
    end
    
    return iHandledTheError
end

Runtime:addEventListener("unhandledError", myUnhandledErrorListener)



이 리스너에 pass 된 이벤트 테이블은 errorMessagestackTrace 파라미터를 가지고 있습니다. 이 에러 메세지는 에러의 result 가 되겠죠 그리고 stack trace 는 에러의 마지막 부분이 될 겁니다. 리스너에서 true 가 리턴되면 팝업 alert 메세지가 뜨는 걸 방지하고 앱이 계속 진행하도록 합니다. false가 return 되면 팝업이 보여지고 앱이 멈추게 되겠죠. (이 경우는 unhandledError 리스너가 적용되지 않은 상황에서도 일어나는 현상입니다.)

다음 daily build 에서 여러분이 보게 될 가장 큰 변화 내용은 런타임 에러가 났을 때의 팝업 메세지 입니다. 런타임 에러를 trap 하고 팝업창이 뜨는 것을 막고 앱이 중지하는 것을 막으시려면 위에서 처럼  unhandledError 리스너를 추가하시면 됩니다.

위의 기능은 daily build 1044 이후부터 적용될 겁니다.


반응형


반응형
Posted on . Written by



build 2013.1043 버전부터 iOS, Android, Mac 그리고 윈도우즈에 모두 적용된 건데요. network api에 새로운 기능을 추가했습니다. 다운로드나 request 같은 네트워크 function들이 이 새로운 기능으로 좀 더 개선 됐습니다. 여기 daily API docs 의 networkRequest에 있는 network와 event 부분을 읽어 보세요. single call에서 텍스트 파일을 업로드하고 bytes transferred 를 보고 하는 것들을 어떻게 하는지 확인해 보세요.


또한 이전 버전과 호환이 되지 않은 새로운 기능 변화가 몇개가 있는데요. 아래 예제에서 보시듯이 event response들은 이제 fileName과 baseDirectory가 포함된 테이블이 됐습니다. 이제 event.response를 string 이 아니라 table로 취급해야 되는 것을 잊지 마세요.

아래에 새로운 event.response table 정보를 어떻게 사용하는지에 대한 예제가 있습니다.


local function networkListener( event )
        if ( event.isError ) then
                print( "Network error - download failed" )
        elseif ( event.phase == "ended" )
                print( "displaying response image file" )
                myImage = display.newImage( event.response.filename, event.response.baseDirectory, 60, 40 )
                myImage.alpha = 0
                transition.to( myImage, { alpha = 1.0 } )
        end
end
 
network.download(
        "http://developer.anscamobile.com/demo/hello.png",
        "GET",
        networkListener,
        "helloCopy.png",
        system.TemporaryDirectory
        )


그리고 코로나에서 지난주와 이번주에 새로운 위젯들을 선보였습니다.

관련 글들은 따로 번역해서 올리지는 않고 아래 링크로 대신 할 께요.

이 글들에 있는 샘플코드를 실행하시던가 새로운 Daily Build 에 예제들을 보시면 도움이 되실 겁니다.




반응형


반응형
Posted on . Written by




수요일의 FAQ 시간입니다. 오늘은 코로나 런타임 에러에 대한 질문들을 다뤄 보겠습니다.




1. My app was working fine and now I’m seeing a pop-up saying an error was found and my app quits. What changed?



안드로이드에서는 build 2013.1030 부터 적용된 건데요, run-time error 가 일어나면 경고창이 뜨고 그 에러에 대한 정보를 보여주게 됩니다. 이전에는 런타임에러가 adb logcat 화면에만 표시되던가 아니면 아무런 표시 없이 지나갔었거든요. 이 기능은 현재 iOS build 에서는 지원되지 않습니다.



2. I don’t remember getting these errors before. Are these real errors?



예 만약 런타임 에러가 났다면 exception이 일어났기 때문입니다. 그러면 그 프로그램은 그 에러 이후의 코드를 실행하지 않습니다. 여러 에러가 있어도 그 에러가 한번에 다 표시되는 게 아니거든요. 혹은 어떤 특정 디바이스에서만 에러가 일어날 수도 있구요.


일반적으로 이런 에러들은 API 에 의해 nil 값이 return 되서 일어나는 경우가 많습니다. 예를 들어 객체의 포인터가 nil일 때 Corona 객체를 remove 하는 경우를 들어보죠. 그리고 nil인 값을 return 한 것을 받아서 그 스트링을 연결하고 display 하는 경우도 예를 들 수 있습니다. 일반적으로 그 값을 사용하려는 함수의 out of scope 인 경우가 많습니다.



Here is one example:


local touchRect = display.newRoundedRect( 0, 50, 70, 30, 10 )
touchRect.x = display.contentCenterX

local count1 = 0
local count2 = 0
local count3 = 0
        
function touchRect:touch( event )
    if event.phase == "ended" then
        count1 = count1 + 1
        count2 = count2 + 1
        count3 = count3 + 1

        text1.text = "Count1 = " .. count1
        text2.text = "Count2 = " .. count2    -- << error here
        text3.text = "Count3 = " .. count3        
    end
    
    return true
end

text1 = display.newText( "Count1 = 0", 10, 100, native.systemFont, 20 )
local text2 = display.newText( "Count2 = 0", 10, 140, native.systemFont, 20 )
text3 = display.newText( "Count3 = 0", 10, 170, native.systemFont, 20 )

touchRect:addEventListener( "touch" )


하얀 사각형을 두드리면 한번에 3개의 count 가 증가하고 그 증가된 값이 display 됩니다. text2.text 가 세팅될 때 버그가 있는데요. 그 에러는 "attempt to index global 'text2' (a nil value)" 입니다. 이유는 text2가 로컬 변수로 정의 됐고 또 touch 함수 이후에 정의 됐기 때문이죠. 이 경우가 바로 함수의 out of scope (범위 밖) 에서 정의 된 것으로 그 값이 nil 이 되는 경우입니다.

시뮬레이터에서 위 코드를 실행하고 사각형을 두드리면 첫번째 counter 가 증가되는 것까지 보실 수 있을 겁니다. 왜냐하면 text2.text 부분에서 에러가 났기 때문이죠. 그 이후의 코드는 실행이 되지 않습니다. 그 사각형을 계속 두드릴 수 있습니다. 그러면 첫번째 counter 만 계속 증가할 겁니다. 사용자 입장에서는 프로그램에 에러없이 잘 실행된다고 느낄 수 있죠.


안드로이드 코드에 저희들이 준 변화는 이 경우 런타임 에러를 감지하고 팝업창에 에러가 난 파일 이름과 line number 를 display 하도록 했습니다. 그러면 그 라인 이후의 코드는 아직 실행이 안 됐다는 것을 알 수 있죠. 이 메세지를 보시려면 콘솔 윈도우를 열어 놓으셔야 합니다. (iOS 에서는 Xcode 가 될 테고 안드로이드 에서는 adb logcat 이 되겠죠.)

위 에러는 text2를 함수가 정의되기 이전에 정의해 버리면 쉽게 고칠 수 있습니다. 혹은 text2에서 local을 없애서 정의 해도 되죠.


text2 = display.newText( "Count2 = 0", 10, 140, native.systemFont, 20 )



3. How do I keep the pop-up from happening when I release my app to Google Play?



이 팝업을 피하는 방법은 두가지가 있습니다.


1) 모든 버그를 찾아서 고치기
2) 문제가 발생할 수 있는 코드 부근에 pcall 구문을 추가하기

앱에서 모든 버그를 찾아서 고치는건 불가능에 가깝습니다. 그래서 에러를 trap 하고 이 에러를 어떻게 할 것인지 선택할 수 있는 런타임 리스너를 추가할 계획을 가지고 있습니다. 앱 스토어용으로 앱을 빌드하고 유저가 에러가 있는 앱을 실행하면 로그가 기록되서 여러분 서버로 이것을 보낼지 아니면 그냥 넘어갈지를 선택해서 실행할 수 있게 됩니다. 이 기능은 현재는 지원되지 않구요 조만간 업데이트 될 Daily Build 에 적용 될 예정입니다.


4. Is there any way to trap the errors myself and not have it quit the app or display a pop-up to the user?



새로운 런타임 에러 리스너가 포함되게 될 Daily Build 를 기다리기 전에 여러분이 하실 수 있는 방법이 있습니다. Lua pcall 구문으로 여러분 코드 블럭을 감싸서 에러를 trap 할 수 있습니다. pcall (protected call) 은 execution status 를 return 하는 call 로 어떤 함수나 메소드든지 call 할 수 있습니다. call 이 제대로 실행 됐다면 true 를 반환할 것이고 런타임 에러 때문에 실패 했다면 false를 반환할 겁니다. 일단 런타임 에러를 trap 하면 pop-up을 띄우거나 app을 quit 하지 않을 겁니다. pcall을 사용하면 약간의 overhead 가 있을 수 있습니다. 그러니까 꼭 에러를 감지해서 어떤 일을 해야 할 경우에만 사용하시기 바랍니다.


The syntax of pcall is:

pcall( f [, ...] )



where f is the function to be called,
and ... is the arguments for the function.

이 구문을 연습해 보기 위해 함수 안의 text2 세팅 부분을 감싸봤습니다. 그리고 이것을 pcall 을 사용해서 call 했습니다. 이 call 의 결과는 status 에 저장이 되서 display 될 겁니다.


local touchRect = display.newRoundedRect( 0, 50, 70, 30, 10 )
touchRect.x = display.contentCenterX

local count1 = 0
local count2 = 0
local count3 = 0

local function setText2( value )
    text2.text = "Count2 = " .. value
end
        
function touchRect:touch( event )
    if event.phase == "ended" then
        count1 = count1 + 1
        count2 = count2 + 1
        count3 = count3 + 1

        text1.text = "Count1 = " .. count1
        
        local status = pcall( setText2, count2 )
        print( "pcall status is ", status )
        
        text3.text = "Count3 = " .. count3        
    end
    
    return true
end

text1 = display.newText( "Count1 = 0", 10, 100, native.systemFont, 20 )
local text2 = display.newText( "Count2 = 0", 10, 140, native.systemFont, 20 )
text3 = display.newText( "Count3 = 0", 10, 170, native.systemFont, 20 )

touchRect:addEventListener( "touch" )


위 코드를 실행시키면 pcall status 가 false가 될 겁니다. 즉 런타임 에러가 났다는 것이죠. counter 1하고 3은 증가할 겁니다. 즉 pcall 이 런타임 에러를 trap 하고 그 안에 런타임 에러가 있더라도 이후의 코드가 실행된다는 것을 알 수 있을 겁니다.

pcall 은 여러분 코드 중에 fail 일 것 같은 구문이 있고 그 부분을 테스트하거나 guard 하고 싶을 때 사용하실 수 있을 겁니다.



5. Why is the error pop-up only in Android builds?



일단 안드로이드쪽을 작업했습니다. 그 이유는 안드로이드 빌드와 관련해서 default permission들을 없애면서 이 에러들을 다뤄야 할 필요성을 느꼈었거든요. 개발자들에게 이 에러들을 감지하고 trap 하는 기능이 제공되면 아주 유용할 거라고 생각했습니다. 그리고 이 기능을 iOS에도 적용할 거고 Mac 과 윈도우즈 시뮬레이터에도 적용할 계획입니다.

현재 릴리즈 버전과 Daily build 에서는 여러분 앱의 버그를 찾을 수 있도록 하기 위해 런타임 에러 정보를 제공합니다. developer build 를 할 때 파일이름과 line number 그리고 에러의 type 을 콘솔을 통해 보실 수 있을 겁니다. Release build (앱 스토어용)에서는 에러 type 만 보실 수 있습니다.


추가적으로 말씀 드린다면 맥 시뮬레이터를 사용하신다면 Corona Simulator가 아니라  Corona Terminal을 start 하는 걸 잊지 마세요. Corona Terminal 은 console 창을 띄우고 나서 Corona Simulator를 실행할 겁니다. 이 콘솔창에는 print, warning 그리고 에러 메세지 등이 display 될 겁니다.


여기까지가 오늘의 FAQ입니다. 도움이 되셨기를 바랍니다.

반응형