Merge pull request #55 from charanrajtc/added-response-format-option

Add contentType option for passing mandatory type
This commit is contained in:
Miroslav Bajtoš 2017-07-20 10:26:37 +02:00 committed by GitHub
commit 68e0aa58d1
3 changed files with 49 additions and 0 deletions

View File

@ -82,6 +82,8 @@ The content type of the response depends on the request's `Accepts` header.
| debug | Boolean    | `false` | If `true`, HTTP responses include all error properties, including sensitive data such as file paths, URLs and stack traces. See [Example output](#example) below. |
| log | Boolean | `true` | If `true`, all errors are printed via `console.error`, including an array of fields (custom error properties) that are safe to include in response messages (both 4xx and 5xx). <br/> If `false`, sends only the error back in the response. |
| safeFields | [String] | `[]` | Specifies property names on errors that are allowed to be passed through in 4xx and 5xx responses. See [Safe error fields](#safe-error-fields) below. |
| defaultType | String | `"json"` | Specify the default response content type to use when the client does not provide any Accepts header.
| negotiateContentType | Boolean | true | Negotiate the response content type via Accepts request header. When disabled, strong-error-handler will always use the default content type when producing responses. Disabling content type negotiation is useful if you want to see JSON-formatted error responses in browsers, because browsers usually prefer HTML and XML over other content types.
### Customizing log format

View File

@ -56,6 +56,18 @@ function negotiateContentProducer(req, logWarning, options) {
debug('Resolved content-type', resolvedContentType);
var contentType = resolvedContentType || defaultType;
if (options.negotiateContentType === false) {
if (SUPPORTED_TYPES.indexOf(options.defaultType) > -1) {
debug('Forcing options.defaultType `%s`',
options.defaultType);
contentType = options.defaultType;
} else {
debug('contentType: `%s` is not supported, ' +
'falling back to contentType: `%s`',
options.defaultType, contentType);
}
}
// to receive _format from user's url param to overide the content type
// req.query (eg /api/Users/1?_format=json will overide content negotiation
// https://github.com/strongloop/strong-remoting/blob/ac3093dcfbb787977ca0229b0f672703859e52e1/lib/http-context.js#L643-L645

View File

@ -628,6 +628,41 @@ describe('strong-error-handler', function() {
.expect('Content-Type', /^application\/json/, done);
});
it('disables content-type negotiation when negotiateContentType=false',
function(done) {
givenErrorHandlerForError(new Error('Some error'), {
negotiateContentType: false,
defaultType: 'application/json',
});
request.get('/')
.set('Accept', 'text/html')
.expect('Content-Type', /^application\/json/, done);
}
);
it('chooses resolved type when negotiateContentType=false + not-supported',
function(done) {
givenErrorHandlerForError(new Error('Some error'), {
negotiateContentType: false,
defaultType: 'unsupported/type',
});
request.get('/')
.set('Accept', 'text/html')
.expect('Content-Type', /^text\/html/, done);
}
);
it('chooses default type when negotiateContentType=false + not-supported ',
function(done) {
givenErrorHandlerForError(new Error('Some error'), {
negotiateContentType: false,
defaultType: 'unsupported/type',
});
request.get('/')
.expect('Content-Type', /^application\/json/, done);
}
);
it('honors order of accepted content-types of text/html', function(done) {
givenErrorHandlerForError(new Error('Some error'), {
defaultType: 'application/json',