jshttp / content-type

Create and parse HTTP Content-Type header
MIT License
131 stars 27 forks source link

how to catch parsing errors #4

Closed thisconnect closed 9 years ago

thisconnect commented 9 years ago

Hi

How would you use this module for parsing content-types expecting that it might throw errors. Is it correct that you either have to try/catch or use Promise ? E.g. for synchronous usage something like this:

var parsed;
try {
    parsed = contentType.parse(type);
}
catch (e){
    console.log(type);
    console.log(href);
    console.error(e.stack);
}

I often use the request module and test against httpbin.org. This http://httpbin.org/response-headers?Content-Type=text%2Fplain%3B+charset%3DUTF-8&Server=httpbin throws the following error:

text%2Fplain%3B charset%3DUTF-8
http://httpbin.org/response-headers?Content-Type=text%2Fplain%3B+charset%3DUTF-8&Server=httpbin
TypeError: invalid media type
    at parse (node_modules/content-type/index.js:128:11)
    ...

I could solve by using decodeURIComponent, something like: contentType.parse(decodeURIComponent(type)); but is this the recommended usage?

dougwilson commented 9 years ago

Hi! So it depends on how you want to handle the parse errors: if they are actually fatal or not.

If they are not fatal, a typical pattern I use is the following:

function tryParse(str) {
  try {
    return contentType.parse(str)
  } catch (e) {
    return undefined
  }
}

And then just determine what to do based on the trutyness of tryParse(type).

Regarding your issue, the type you are showing there is in a query string. When you are trying to read from a query string, you have to perform the decoding that is specific to a query string. The best way would be to simply use the built-in querystring module from Node.js:

var url = require('url')
// ...
var href = 'http://httpbin.org/response-headers?Content-Type=text%2Fplain%3B+charset%3DUTF-8&Server=httpbin'
var parsed = contentType.parse(url.parse(href, true).query['Content-Type'])

The true argument to url.parse will mean that the querystring module will be invoked and the query property will contain the parsed results, which means that they are also decoded for you.

thisconnect commented 9 years ago

thanks for your quick response! I will use try catch.

For the second question it was the request module returning text%2Fplain%3B charset%3DUTF-8 but I just realized it was my mistake. For some reason I was doing something stupid like

var href = 'http://httpbin.org/response-headers?Content-Type=text%2Fplain%3B+charset%3DUTF-8&Server=httpbin'

request.get(encodeURI(decodeURI(href)), function (error, response, body) {
  console.log(response.headers['content-type'])
})

also thanks for querystring recommendation.

dougwilson commented 9 years ago

It was no problem helping out :) !