日別アーカイブ: 2013年8月9日

WebSocketのエンコード・デコード時のエラー

先日書いたWebsocketでJSONデータをやり取りしたブログだけど、エラー出力をきちんとしていなくてはまった。

Decoder.Text<T>のdecodeメソッド内でExceptionが発生した場合に、明示的にログ・スタックトレースの出力をしておかないと特にスタックトレース等が出力されないでdecodeメソッド(とそれから呼ばれる@OnMessage)が終了してしまう。(コンソールにエラーがつらつら出るようなことは無い。)

そのため、下みたいな感じで明示的にエラーあったことを出力してやらないとわかりにくい。

    @Override
    public TestData decode(String inputString) throws DecodeException {
        try{
            JsonObject jsonObject = Json.createReader(new StringReader(inputString)).readObject();
            return  new TestData(jsonObject);
        } catch(Exception e){
            DecodeException de = 
                    new DecodeException(inputString,"decode失敗", (Throwable)e);
            Logger.getLogger(TestDecoder.class.getName()).log(
                    Level.SEVERE, null, de);
            throw de;
        }
    }

Encoder.Text<T>のencodeメソッドも似たような話がある。

    @Override
    public String encode(TestData paramData) throws EncodeException {
        try{
            JsonObject model = Json.createObjectBuilder()
                       .add("message", paramData.getMessage())
                       .add("sessionId",paramData.getSessionId())
                       .add("messageTime", formatDate(paramData.getMessageTime()))
                       .build();
            return model.toString();
        } catch( Exception e ){
            EncodeException ee =  
                    new EncodeException(paramData, "encode失敗",  (Throwable)e);
            Logger.getLogger(TestEncoder.class.getName()).log(
                    Level.SEVERE, null, ee);
            throw ee;
        }
    }

一応decodeでエラーを発生させたときのログサンプル

重大: javax.websocket.DecodeException: decode失敗
    at jp.co.epea.first.json.TestDecoder.decode(TestDecoder.java:33)
    at jp.co.epea.first.json.TestDecoder.decode(TestDecoder.java:1)
    at org.glassfish.tyrus.core.EndpointWrapper.decodeCompleteMessage(EndpointWrapper.java:278)
    at org.glassfish.tyrus.core.SessionImpl.notifyMessageHandlers(SessionImpl.java:386)
    at org.glassfish.tyrus.core.EndpointWrapper.onMessage(EndpointWrapper.java:495)
    at org.glassfish.tyrus.server.TyrusEndpoint.onMessage(TyrusEndpoint.java:174)
    at org.glassfish.tyrus.websockets.DefaultWebSocket.onMessage(DefaultWebSocket.java:156)
    at org.glassfish.tyrus.websockets.frametypes.TextFrameType.respond(TextFrameType.java:66)
    at org.glassfish.tyrus.websockets.DataFrame.respond(DataFrame.java:102)
    at org.glassfish.tyrus.servlet.TyrusHttpUpgradeHandler.onDataAvailable(TyrusHttpUpgradeHandler.java:113)
    at org.apache.catalina.connector.InputBuffer$ReadHandlerImpl.processDataAvailable(InputBuffer.java:488)
    at org.apache.catalina.connector.InputBuffer$ReadHandlerImpl.onDataAvailable(InputBuffer.java:453)
    at org.glassfish.grizzly.http.io.InputBuffer.append(InputBuffer.java:855)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:222)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
    at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.ClassCastException: org.glassfish.json.JsonStringImpl cannot be cast to javax.json.JsonNumber
    at org.glassfish.json.JsonObjectBuilderImpl$JsonObjectImpl.getJsonNumber(JsonObjectBuilderImpl.java:171)
    at jp.co.epea.first.json.TestData.<init>(TestData.java:21)
    at jp.co.epea.first.json.TestDecoder.decode(TestDecoder.java:30)
    ... 27 more