ZnClient Error - Improper store into indexable object

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

ZnClient Error - Improper store into indexable object

Edward Povazan
I am playing around with Zinc, and I get an
"Error - Improper store into indexable object”
at
ZnBufferedWriteStream>>nextPut:

My Workspace:
-----
| response |
response := ZnClient new
        url:'http://amazon.com';
        get;
        response.
       
response writeOn: Transcript.
Transcript flush
-----

The reason is that instead of a Character, there is a SmallInteger of value 10 being added at ByteString>>at:put: (and 10 is a linefeed).

Also the string in the entity is a WideString (ZnUTF8Encoder>>next:putAll:startingAt:toStream is where the choice is made to decode a ByteString vs WideString).

Is this a bug? Running on Pharo 3. My newb debugging skills don’t go further :( Other sites that fail are reddit.com, news.ycombinator.com.

Thanks,
-Ed
Reply | Threaded
Open this post in threaded view
|

Re: ZnClient Error - Improper store into indexable object

Sven Van Caekenberghe-2
Hi Edward,

> On 29 Dec 2014, at 17:19, Edward Povazan <[hidden email]> wrote:
>
> I am playing around with Zinc, and I get an
> "Error - Improper store into indexable object”
> at
> ZnBufferedWriteStream>>nextPut:
>
> My Workspace:
> -----
> | response |
> response := ZnClient new
> url:'http://amazon.com';
> get;
> response.
>
> response writeOn: Transcript.
> Transcript flush
> -----
>
> The reason is that instead of a Character, there is a SmallInteger of value 10 being added at ByteString>>at:put: (and 10 is a linefeed).
>
> Also the string in the entity is a WideString (ZnUTF8Encoder>>next:putAll:startingAt:toStream is where the choice is made to decode a ByteString vs WideString).
>
> Is this a bug? Running on Pharo 3. My newb debugging skills don’t go further :( Other sites that fail are reddit.com, news.ycombinator.com.
>
> Thanks,
> -Ed

Short answer:

Zinc writes to or reads from binary streams, the Transcript is a character stream. I know that what you are trying to do is actually in the documentation and in the API, and it normally works, just not in all cases. It is better to use inspection to look at what is going on, you'll get a much more structured (object-oriented) view of what is going on. I would suggest inspecting the ZnClient instance, which will hold the state of the last request and response.

Long answer:

If you try

| response |
response := ZnClient new
        url:'http://stfx.eu/small.html';
        get;
        response.
       
response writeToTranscript.

It will work and print

HTTP/1.1 200 OK
X-Pad: avoid browser bug
Date: Mon, 29 Dec 2014 18:56:37 GMT
Content-Length: 113
Etag: "202f9-71-4c7ae94364f1e"
Server: Apache/2.2.22 (Ubuntu)
Accept-Ranges: bytes
Last-Modified: Mon, 20 Aug 2012 08:48:51 GMT
Vary: Accept-Encoding
Content-Type: text/html

<html>
<head><title>Small</title></head>
<body><h1>Small</h1><p>This is a small HTML document</p></body>
</html>

So what is the difference ?

The fact that the responses that you get from the website you mention are using chunked transfer encoding (http://en.wikipedia.org/wiki/Chunked_transfer_encoding). Zinc deals with this in both ways, while reading a response, but also while writing a response (which is what you are trying to do here).

Here is how you disable chunked transfer encoding so that you can write the response to the Transcript

| response |
response := ZnClient new
        url:'http://amazon.com';
        get;
        response.
       
response headers removeKey: 'Transfer-Encoding'.
response writeToTranscript.

Zinc manages to write to the Transcript in most cases by cheating a bit: it wraps a ZnBivalentWriteStream around another stream when needed - such a stream can do both binary and character writing at the same time (though the result is only good for quick and dirty debugging, since it is not 100% correct).

I hope the long explanation didn't make it worse ;-)

HTH,

Sven

PS: BTW, in Pharo 4 with Zinc #bleedingEdge you get even nicer and more high level presentations of Zinc objects in GT-Inspector !


Reply | Threaded
Open this post in threaded view
|

Re: ZnClient Error - Improper store into indexable object

Sven Van Caekenberghe-2

> On 29 Dec 2014, at 20:16, Sven Van Caekenberghe <[hidden email]> wrote:
>
> Hi Edward,
>
>> On 29 Dec 2014, at 17:19, Edward Povazan <[hidden email]> wrote:
>>
>> I am playing around with Zinc, and I get an
>> "Error - Improper store into indexable object”
>> at
>> ZnBufferedWriteStream>>nextPut:
>>
>> My Workspace:
>> -----
>> | response |
>> response := ZnClient new
>> url:'http://amazon.com';
>> get;
>> response.
>>
>> response writeOn: Transcript.
>> Transcript flush
>> -----
>>
>> The reason is that instead of a Character, there is a SmallInteger of value 10 being added at ByteString>>at:put: (and 10 is a linefeed).
>>
>> Also the string in the entity is a WideString (ZnUTF8Encoder>>next:putAll:startingAt:toStream is where the choice is made to decode a ByteString vs WideString).
>>
>> Is this a bug? Running on Pharo 3. My newb debugging skills don’t go further :( Other sites that fail are reddit.com, news.ycombinator.com.
>>
>> Thanks,
>> -Ed
>
> Short answer:
>
> Zinc writes to or reads from binary streams, the Transcript is a character stream. I know that what you are trying to do is actually in the documentation and in the API, and it normally works, just not in all cases. It is better to use inspection to look at what is going on, you'll get a much more structured (object-oriented) view of what is going on. I would suggest inspecting the ZnClient instance, which will hold the state of the last request and response.
>
> Long answer:
>
> If you try
>
> | response |
> response := ZnClient new
> url:'http://stfx.eu/small.html';
> get;
> response.
>
> response writeToTranscript.
>
> It will work and print
>
> HTTP/1.1 200 OK
> X-Pad: avoid browser bug
> Date: Mon, 29 Dec 2014 18:56:37 GMT
> Content-Length: 113
> Etag: "202f9-71-4c7ae94364f1e"
> Server: Apache/2.2.22 (Ubuntu)
> Accept-Ranges: bytes
> Last-Modified: Mon, 20 Aug 2012 08:48:51 GMT
> Vary: Accept-Encoding
> Content-Type: text/html
>
> <html>
> <head><title>Small</title></head>
> <body><h1>Small</h1><p>This is a small HTML document</p></body>
> </html>
>
> So what is the difference ?
>
> The fact that the responses that you get from the website you mention are using chunked transfer encoding (http://en.wikipedia.org/wiki/Chunked_transfer_encoding). Zinc deals with this in both ways, while reading a response, but also while writing a response (which is what you are trying to do here).
>
> Here is how you disable chunked transfer encoding so that you can write the response to the Transcript
>
> | response |
> response := ZnClient new
> url:'http://amazon.com';
> get;
> response.
>
> response headers removeKey: 'Transfer-Encoding'.
> response writeToTranscript.
>
> Zinc manages to write to the Transcript in most cases by cheating a bit: it wraps a ZnBivalentWriteStream around another stream when needed - such a stream can do both binary and character writing at the same time (though the result is only good for quick and dirty debugging, since it is not 100% correct).

I forgot to add that in the case of chunked transfer encoding, the bivalent property of the output stream gets lost because it gets wrapped in both a ZnChunkedWriteStream and a ZnBufferedWriteStream.

> I hope the long explanation didn't make it worse ;-)
>
> HTH,
>
> Sven
>
> PS: BTW, in Pharo 4 with Zinc #bleedingEdge you get even nicer and more high level presentations of Zinc objects in GT-Inspector !
>


Reply | Threaded
Open this post in threaded view
|

Re: ZnClient Error - Improper store into indexable object

Edward Povazan
In reply to this post by Sven Van Caekenberghe-2
Sven, thank you so much for the detailed explanation.
I used it to look at the debugger again so I could reformulate the way I look for bugs. I’d was looking backwards from the error, but had I started at the DoIt, I would have seen the ZnBivalentWriteStream and seen the class comment. Moreover, I would have realized it all starts with the Transcript.
I guess habits from my other environment (iOS, where the stack leads into closed source). And here in Pharo I can inspect the MethodContext and see the program counter :)

Thanks again,
-Edward

> On Dec 29, 2014, at 11:16 AM, Sven Van Caekenberghe <[hidden email]> wrote:
>
> Hi Edward,
>
>> On 29 Dec 2014, at 17:19, Edward Povazan <[hidden email]> wrote:
>>
>> I am playing around with Zinc, and I get an
>> "Error - Improper store into indexable object”
>> at
>> ZnBufferedWriteStream>>nextPut:
>>
>> My Workspace:
>> -----
>> | response |
>> response := ZnClient new
>> url:'http://amazon.com';
>> get;
>> response.
>>
>> response writeOn: Transcript.
>> Transcript flush
>> -----
>>
>> The reason is that instead of a Character, there is a SmallInteger of value 10 being added at ByteString>>at:put: (and 10 is a linefeed).
>>
>> Also the string in the entity is a WideString (ZnUTF8Encoder>>next:putAll:startingAt:toStream is where the choice is made to decode a ByteString vs WideString).
>>
>> Is this a bug? Running on Pharo 3. My newb debugging skills don’t go further :( Other sites that fail are reddit.com, news.ycombinator.com.
>>
>> Thanks,
>> -Ed
>
> Short answer:
>
> Zinc writes to or reads from binary streams, the Transcript is a character stream. I know that what you are trying to do is actually in the documentation and in the API, and it normally works, just not in all cases. It is better to use inspection to look at what is going on, you'll get a much more structured (object-oriented) view of what is going on. I would suggest inspecting the ZnClient instance, which will hold the state of the last request and response.
>
> Long answer:
>
> If you try
>
> | response |
> response := ZnClient new
> url:'http://stfx.eu/small.html';
> get;
> response.
>
> response writeToTranscript.
>
> It will work and print
>
> HTTP/1.1 200 OK
> X-Pad: avoid browser bug
> Date: Mon, 29 Dec 2014 18:56:37 GMT
> Content-Length: 113
> Etag: "202f9-71-4c7ae94364f1e"
> Server: Apache/2.2.22 (Ubuntu)
> Accept-Ranges: bytes
> Last-Modified: Mon, 20 Aug 2012 08:48:51 GMT
> Vary: Accept-Encoding
> Content-Type: text/html
>
> <html>
> <head><title>Small</title></head>
> <body><h1>Small</h1><p>This is a small HTML document</p></body>
> </html>
>
> So what is the difference ?
>
> The fact that the responses that you get from the website you mention are using chunked transfer encoding (http://en.wikipedia.org/wiki/Chunked_transfer_encoding). Zinc deals with this in both ways, while reading a response, but also while writing a response (which is what you are trying to do here).
>
> Here is how you disable chunked transfer encoding so that you can write the response to the Transcript
>
> | response |
> response := ZnClient new
> url:'http://amazon.com';
> get;
> response.
>
> response headers removeKey: 'Transfer-Encoding'.
> response writeToTranscript.
>
> Zinc manages to write to the Transcript in most cases by cheating a bit: it wraps a ZnBivalentWriteStream around another stream when needed - such a stream can do both binary and character writing at the same time (though the result is only good for quick and dirty debugging, since it is not 100% correct).
>
> I hope the long explanation didn't make it worse ;-)
>
> HTH,
>
> Sven
>
> PS: BTW, in Pharo 4 with Zinc #bleedingEdge you get even nicer and more high level presentations of Zinc objects in GT-Inspector !
>
>


Reply | Threaded
Open this post in threaded view
|

Re: ZnClient Error - Improper store into indexable object

stepharo
In reply to this post by Sven Van Caekenberghe-2
Sven
this is a really cool answer!
May be we should add that somewhere :)

Stef
Le 29/12/14 20:16, Sven Van Caekenberghe a écrit :

> Hi Edward,
>
>> On 29 Dec 2014, at 17:19, Edward Povazan <[hidden email]> wrote:
>>
>> I am playing around with Zinc, and I get an
>> "Error - Improper store into indexable object”
>> at
>> ZnBufferedWriteStream>>nextPut:
>>
>> My Workspace:
>> -----
>> | response |
>> response := ZnClient new
>> url:'http://amazon.com';
>> get;
>> response.
>>
>> response writeOn: Transcript.
>> Transcript flush
>> -----
>>
>> The reason is that instead of a Character, there is a SmallInteger of value 10 being added at ByteString>>at:put: (and 10 is a linefeed).
>>
>> Also the string in the entity is a WideString (ZnUTF8Encoder>>next:putAll:startingAt:toStream is where the choice is made to decode a ByteString vs WideString).
>>
>> Is this a bug? Running on Pharo 3. My newb debugging skills don’t go further :( Other sites that fail are reddit.com, news.ycombinator.com.
>>
>> Thanks,
>> -Ed
> Short answer:
>
> Zinc writes to or reads from binary streams, the Transcript is a character stream. I know that what you are trying to do is actually in the documentation and in the API, and it normally works, just not in all cases. It is better to use inspection to look at what is going on, you'll get a much more structured (object-oriented) view of what is going on. I would suggest inspecting the ZnClient instance, which will hold the state of the last request and response.
>
> Long answer:
>
> If you try
>
> | response |
> response := ZnClient new
> url:'http://stfx.eu/small.html';
> get;
> response.
>
> response writeToTranscript.
>
> It will work and print
>
> HTTP/1.1 200 OK
> X-Pad: avoid browser bug
> Date: Mon, 29 Dec 2014 18:56:37 GMT
> Content-Length: 113
> Etag: "202f9-71-4c7ae94364f1e"
> Server: Apache/2.2.22 (Ubuntu)
> Accept-Ranges: bytes
> Last-Modified: Mon, 20 Aug 2012 08:48:51 GMT
> Vary: Accept-Encoding
> Content-Type: text/html
>
> <html>
> <head><title>Small</title></head>
> <body><h1>Small</h1><p>This is a small HTML document</p></body>
> </html>
>
> So what is the difference ?
>
> The fact that the responses that you get from the website you mention are using chunked transfer encoding (http://en.wikipedia.org/wiki/Chunked_transfer_encoding). Zinc deals with this in both ways, while reading a response, but also while writing a response (which is what you are trying to do here).
>
> Here is how you disable chunked transfer encoding so that you can write the response to the Transcript
>
> | response |
> response := ZnClient new
> url:'http://amazon.com';
> get;
> response.
>
> response headers removeKey: 'Transfer-Encoding'.
> response writeToTranscript.
>
> Zinc manages to write to the Transcript in most cases by cheating a bit: it wraps a ZnBivalentWriteStream around another stream when needed - such a stream can do both binary and character writing at the same time (though the result is only good for quick and dirty debugging, since it is not 100% correct).
>
> I hope the long explanation didn't make it worse ;-)
>
> HTH,
>
> Sven
>
> PS: BTW, in Pharo 4 with Zinc #bleedingEdge you get even nicer and more high level presentations of Zinc objects in GT-Inspector !
>
>
>