Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errors passed to next are not mapped #7

Closed
tpluscode opened this issue Oct 25, 2019 · 7 comments · Fixed by #11
Closed

Errors passed to next are not mapped #7

tpluscode opened this issue Oct 25, 2019 · 7 comments · Fixed by #11

Comments

@tpluscode
Copy link
Contributor

Current

Express has a built-in way for returning errors from any middleware with the next(error) call. It appears that errors returned this way do not get converted into problem+json because the handler is an ordinary middleware callback.

Desired

Any error returned in the standard way should be intercepted and converted into a mapped problem document.

Proposal

I think that following best practices of express, the 4-parameter error callback could be used instead. Thus the code can actually be simplified. Here's my implementation:

import { IMappingStrategy } from 'http-problem-details-mapper'

class HttpProblemResponseOptions {
  public strategy: IMappingStrategy;
}

export function HttpProblemResponse (options: HttpProblemResponseOptions) {
  const { strategy } = options

  return (err, req, res, next) => {
    let problem = strategy.map(err)

    res.statusCode = problem.status
    res.setHeader('Content-Type', 'application/problem+json')
    res.send(JSON.stringify(problem))
  }
}

The only difference is that it must be the last app.use call when setting up express

const server = express()
-server.use(HttpProblemResponse({strategy}))

server.get('/', async (req: express.Request, res: express.Response): Promise<any> => {
  return res.send(new NotFoundError({type: 'customer', id: '123' }))
})
+server.use(HttpProblemResponse({strategy}))
@AlexZeitler
Copy link
Contributor

Makes sense. Would you mind sending a PR?

@tpluscode
Copy link
Contributor Author

Definitely. This will be a breaking change the if implemented as above. Is that fine, or would you want to keep compatibility?

@AlexZeitler
Copy link
Contributor

AlexZeitler commented Oct 25, 2019

The reason why we didn't choose the 4-parameter error callback is that we've often seen loggers being registered using last app.use call to handle global exceptions.

I think we should handle this in some way.

@tpluscode
Copy link
Contributor Author

Ok, I re-read your comment and I think I was right earlier. This seems in line with the express docs. The global logger must simply pass on the error and the HttpProblemResponse comes last:

server.use(function logErrors (err, req, res, next) {
  console.error(err.stack)
  next(err)
})
server.use(HttpProblemResponse({strategy}))

@AlexZeitler
Copy link
Contributor

Ok, I think we should use the 4-parameter error callback and add your sample to the docs.

@tpluscode
Copy link
Contributor Author

About the docs. I notice that they instruct to implement a IMappingStrategy but there is actually such a default implementation so seems redundant?

tpluscode added a commit to tpluscode/express-http-problem-details that referenced this issue Oct 25, 2019
so that it can also handle any caught exception and intercept calls to `next(err)`

fixes PDMLab#7
@AlexZeitler
Copy link
Contributor

Yes, you're right. I guess it's a copy/paste failure from the http-problem-details-mapper repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants