Skip to content
This repository has been archived by the owner on Jan 21, 2022. It is now read-only.

Commit

Permalink
feat: Make onError middleware option affect middleware behaviour, exp…
Browse files Browse the repository at this point in the history
…ose a strict middleware variant for parity with the Next case
  • Loading branch information
yourtallness committed Apr 21, 2021
1 parent 69dc101 commit 646703a
Show file tree
Hide file tree
Showing 14 changed files with 658 additions and 2,574 deletions.
60 changes: 47 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,38 +391,72 @@ let smsMessage = await clerk.smsMessages.createSMSMessage({ message, phoneNumber

## Error handling

The error handling is pretty generic at the moment but more fine grained errors are coming soon ™.
The error handling is pretty generic at the moment but more fine-grained errors are coming soon ™.

## Express middleware

For usage with [Express](https://github.com/expressjs/express), this package also exports a `ClerkExpressMiddleware`
function that can be used in the standard manner:
For usage with [Express](https://github.com/expressjs/express), this package also exports `ClerkExpressWithSession` (lax) & `ClerkExpressRequireSession` (strict)
middlewares that can be used in the standard manner:

```
import { ClerkExpressMiddleware } from 'sdk-server-node';
import { ClerkWithSession } from 'sdk-server-node';
// Initialize express app the usual way
const options = {
onError: function() {} // Function to call if the middleware encounters or fails to authenticate, can be used to provide logging etc
};
app.use(ClerkExpressMiddleware(options));
app.use(ClerkWithSession());
```

The middleware will set the Clerk session on the request object as `req.session` and simply call the next middleware.
The `ClerkWithSession` middleware will set the Clerk session on the request object as `req.session` and then call the next middleware.

You can then implement your own logic for handling a logged in or logged out user in your express endpoints or custom
middleware, depending on whether they are trying to access a public or protected resource.
You can then implement your own logic for handling a logged-in or logged-out user in your express endpoints or custom
middleware, depending on whether your users are trying to access a public or protected resource.

If you want to use the express middleware of your custom `Clerk` instance, you can use:

```
app.use(clerk.expressMiddleware(options));
app.use(clerk.expressWithSession());
```

Where `clerk` is your own instance.

If you prefer that the middleware renders a 401 (Unauthenticated) itself, you can use the following variant instead:

```
import { ClerkExpressRequireSession } from 'sdk-server-node';
app.use(ClerkExpressRequireSession());
```

### onError option

The Express middleware supports an `options` object as an optional argument.
The only key only supported is `onError` for providing your own error handler.

The `onError` function, if provided, should take an `Error` argument (`onError(error)`).

Depending on the return value, it can affect the behavior of the middleware as follows:

- If an `Error` is returned, the middleware will call `next(err)` with that error. If the `err` has a `statusCode` it will indicate to Express what HTTP code the response should have.
- If anything other than an `Error` is returned (or nothing is returned at all), then the middleware will call `next()` without arguments

The default implementations unless overridden are:

```
// defaultOnError swallows the error
defaultOnError(error: Error) {
console.error(error.message);
}
// strictOnError returns the error so that Express will halt the request chain
strictOnError(error: Error) {
console.error(error.message);
return error;
}
```

`defaultOnError` is used in the lax middleware variant and `strictOnError` in the strict variant.

## Next

The current package also offers a way of making
Expand Down
4 changes: 2 additions & 2 deletions examples/express/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"type": "module",
"dependencies": {
"@clerk/clerk-sdk-node": "latest",
"dotenv": "^8.2.0",
"express": "^4.17.1"
"dotenv": "latest",
"express": "latest"
}
}
25 changes: 18 additions & 7 deletions examples/express/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,33 @@
// node --require dotenv/config server.mjs

import express from 'express';
import { ClerkExpressMiddleware } from '@clerk/clerk-sdk-node';
import { ClerkExpressWithSession, ClerkExpressRequireSession } from '@clerk/clerk-sdk-node';

const port = process.env.PORT;

function onError(error) {
console.log(error.message);
}

var app = express();

app.use(ClerkExpressMiddleware({ onError }));
function errorHandler (err, req, res, next) {
const statusCode = err.statusCode || 500;
const body = err.data || { error: err.message };

res
.status(statusCode)
.json(body);
}

// Root path uses lax middleware
app.get('/', ClerkExpressWithSession(), (req, res) => {
res.json(req.session);
});

app.get('/', (req, res) => {
// /require-session path uses strict middleware
app.get('/require-session', ClerkExpressRequireSession(), (req, res) => {
res.json(req.session);
});

app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});

app.use(errorHandler);
4 changes: 2 additions & 2 deletions examples/express/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ destroy@~1.0.4:
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=

dotenv@^8.2.0:
dotenv@latest:
version "8.2.0"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
Expand Down Expand Up @@ -285,7 +285,7 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=

express@^4.17.1:
express@latest:
version "4.17.1"
resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==
Expand Down
10 changes: 5 additions & 5 deletions examples/next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next",
"version": "0.1.0",
"version": "0.2.0",
"private": true,
"scripts": {
"dev": "next dev",
Expand All @@ -9,8 +9,8 @@
},
"dependencies": {
"@clerk/clerk-sdk-node": "latest",
"next": "10.0.5",
"react": "17.0.1",
"react-dom": "17.0.1"
"next": "latest",
"react": "latest",
"react-dom": "latest"
}
}
}
2 changes: 1 addition & 1 deletion examples/next/pages/api/require-session.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ function handler(req, res) {
res.json(req.session || { empty: true });
}

export default requireSession(handler, { onError: error => console.log(error.message) });
export default requireSession(handler);
2 changes: 1 addition & 1 deletion examples/next/pages/api/with-session.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ function handler(req, res) {
res.json(req.session || { empty: true });
}

export default withSession(handler, { onError: error => console.log(error.message) });
export default withSession(handler);
Loading

0 comments on commit 646703a

Please sign in to comment.