On 13 Dec 2017, at 10:14, Norbert Hartl <norbert@hartl.name> wrote:
To make your core a little bit more reliable you should not catch the general error but a NeoJSONParseError. And you need to guard the dictionary access. There is no guarantee you get something back that inlcudes key success and message.
Yes, indeed. Also, a better REST API (not something you can change) would not return 200 OK with an error in the payload, but would return a 404 Not Found with a proper error object as payload. FWIW, there are a couple of more sophisticated examples, like in NeoJSONMappingTests and NeoJSONExamplesTests, with comments that do various special cases.
Norbert
Am 13.12.2017 um 09:54 schrieb Ben Coman <btc@openinworld.com>:
hi Sven,
On 13 Dec 2017, at 07:59, Ben Coman <btc@openinworld.com> wrote:
With... Object subclass: #BittrexResponse instanceVariableNames: 'success message result' classVariableNames: '' package: 'Bittrex'
Object subclass: #BittrexMarketSummary instanceVariableNames: 'MarketName High Low Volume Last BaseVolume TimeStamp Bid Ask OpenBuyOrders OpenSellOrders PrevDay Created DisplayMarketName' classVariableNames: '' package: 'Bittrex'
this code works great when the response holds good data... ZnClient new url: 'https://bittrex.com/api/v1.1/public/getmarketSummary?market=BTC-LTC'; enforceHttpSuccess: true; accept: ZnMimeType applicationJson; contentReader: [ :entity | |reader| reader := (NeoJSONReader on: entity readStream). reader for: BittrexResponse do: [:m| m mapInstVar: #success. m mapInstVar: #message. (m mapInstVar: #result) valueSchema: #ResultArray]. reader for: #ResultArray customDo: [ :mapping | mapping listOfElementSchema: BittrexMarketSummary ]. reader mapInstVarsFor: BittrexMarketSummary. reader nextAs: BittrexResponse ]; get.
i.e. a raw response looking like this.... (ZnClient new url: 'https://bittrex.com/api/v1.1/public/getmarketsummary?market=BTC-LTC'; get) inspect. ==> "'{""success"":true,""message"":"",""result"":[{""MarketName"":""BTC-LTC"",""High"":0.01982450,""Low"":0.01285257,""Volume"":1436429.81313360,""Last"":0.01842000,""BaseVolume"":24841.17217724,""TimeStamp"":""2017-12-13T05:56:25.937"",""Bid"":0.01840001,""Ask"":0.01842000,""OpenBuyOrders"":10140,""OpenSellOrders"":6306,""PrevDay"":0.01439800,""Created"":""2014-02-13T00:00:00""}]}'"
But for bad response looking like this... (ZnClient new url: 'https://bittrex.com/api/v1.1/public/getmarketsummary?market=INVALID'; get) inspect. ==> {"success":false,"message":"INVALID_MARKET","result":null}
the JSON handling code fails deep in the call stack with an error "NeoJSONParseError: [ expected" which is not so friendly for users of the Bittrex library.
What are the different/recommended approaches with Zinc for catching JSON errors such that I can pass "message" as a higher level Error up the stack to the Bittrex user.
cheers -ben
On 13 December 2017 at 15:37, Sven Van Caekenberghe <sven@stfx.eu> wrote: BTW, this is no about Zinc, but about NeoJSON.
This is what I meant with variability that is hard to capture with a simple static type schema.
I have no time to try myself right now, but a custom mapping for ivar result (as in a block) might be able to see the difference and act accordingly.
okay. So I played around tracing this through the debugger and for anyone else with a similar need later, I ended up with the following...
response := (ZnClient new url: 'https://bittrex.com/api/v1.1/public/getticker?market=INVALID'; enforceHttpSuccess: true; accept: ZnMimeType applicationJson; contentReader: [ :entity | [ |reader| reader := (NeoJSONReader on: entity readStream). reader for: BittrexResponse do: [:m| m mapInstVar: #success. m mapInstVar: #message. (m mapInstVar: #result) valueSchema: BittrexTicker ]. reader mapInstVarsFor: BittrexTicker. reader nextAs: BittrexResponse ] on: Error do: [ :err | |json| json := NeoJSONReader fromString: entity contents. (json at: 'success') ifFalse: [ self error: (json at: 'message') ] ifTrue: [ self error: 'UKNOWN ERROR' ] ] ]) get.
for which I get a nice pre-debug window titled "Error: INVALID_MARKET"
cheers -ben