Skip to content

Commit

Permalink
Merge branch 'main' into feat/forms-1240-external-api
Browse files Browse the repository at this point in the history
  • Loading branch information
usingtechnology committed Jun 6, 2024
2 parents 9c431ef + c0ba285 commit 2231f26
Show file tree
Hide file tree
Showing 19 changed files with 761 additions and 407 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/cypress-ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Cypress Tests
on:
workflow_dispatch:
inputs:
pr-number:
description: Pull request number
required: false
type: string

jobs:
cypress-run:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: cache
uses: actions/cache@v4
with:
path: "tests/functional"
key: node-modules-${{ hashFiles('tests/functional/package.json') }}


- name: cypress install
uses: cypress-io/github-action@v6
with:
working-directory: '${{ github.workspace }}/tests/functional'
env:
CYPRESS_keycloakUsername: ${{secrets.keycloakUsername}}
CYPRESS_keycloakPassword: ${{secrets.keycloakPassword}}
CYPRESS_depEnv: ${{ github.event.inputs.pr-number }}

- uses: actions/upload-artifact@v4
if: failure()
with:
name: cypress-screenshots
path: '${{ github.workspace }}/tests/functional/screenshots'

2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ build
coverage
dist
**/src/formio
**/cypress/**/screenshots
**/cypress/**/videos
screenshots
node_modules

# Ignore only top-level package-lock.json
Expand Down
2 changes: 1 addition & 1 deletion app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ apiRouter.get('/api', (_req, res) => {
// Host API endpoints
apiRouter.use(config.get('server.apiPath'), v1Router);
app.use(config.get('server.basePath'), apiRouter);
app.use(middleware.dataErrors);
app.use(middleware.errorHandler);

// Host the static frontend assets
const staticFilesPath = config.get('frontend.basePath');
Expand Down
26 changes: 7 additions & 19 deletions app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,11 @@
"dependencies": {
"@json2csv/node": "^6.1.3",
"@json2csv/transforms": "^6.1.3",
"api-problem": "^7.0.4",
"api-problem": "^9.0.2",
"aws-sdk": "^2.1376.0",
"axios": "^0.28.1",
"axios-oauth-client": "^1.5.0",
"axios-token-interceptor": "^0.2.0",
"body-parser": "^1.20.2",
"bytes": "^3.1.2",
"compression": "^1.7.4",
"config": "^3.3.9",
Expand All @@ -64,7 +63,6 @@
"express-rate-limit": "^7.2.0",
"express-winston": "^4.2.0",
"falsey": "^1.0.0",
"fast-json-patch": "^3.1.1",
"fs-extra": "^10.1.0",
"handlebars": "^4.7.8",
"jose": "^5.2.2",
Expand Down
36 changes: 0 additions & 36 deletions app/src/forms/common/middleware/dataErrors.js

This file was deleted.

77 changes: 77 additions & 0 deletions app/src/forms/common/middleware/errorHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const Problem = require('api-problem');
const Objection = require('objection');

/**
* Given a subclass of DBError will create and throw the corresponding Problem.
* If the error is of an unknown type it will not be converted.
*
* @param {DBError} error the error to convert to a Problem.
* @returns nothing
*/
const _throwObjectionProblem = (error) => {
if (error instanceof Objection.DataError) {
throw new Problem(422, {
detail: 'Sorry... the database does not like the data you provided :(',
});
}

if (error instanceof Objection.NotFoundError) {
throw new Problem(404, {
detail: "Sorry... we still haven't found what you're looking for :(",
});
}

if (error instanceof Objection.ConstraintViolationError) {
throw new Problem(422, {
detail: 'Constraint Violation Error',
});
}

if (error instanceof Objection.ValidationError) {
throw new Problem(422, {
detail: 'Validation Error',
errors: error.data,
});
}
};

/**
* Send an error response for all errors except 500s, which are handled by the
* code in app.js.
*
* @param {*} err the Error that occurred.
* @param {*} _req the Express object representing the HTTP request - unused.
* @param {*} res the Express object representing the HTTP response.
* @param {*} next the Express chaining function.
* @returns nothing
*/
module.exports.errorHandler = async (err, _req, res, next) => {
try {
if (err instanceof Objection.DBError || err instanceof Objection.NotFoundError || err instanceof Objection.ValidationError) {
_throwObjectionProblem(err);
}

// Express throws Errors that are not Problems, but do have an HTTP status
// code. For example, 400 is thrown when POST bodies are malformed JSON.
if (!(err instanceof Problem) && (err.status || err.statusCode)) {
throw new Problem(err.status || err.statusCode, {
detail: err.message,
});
}

// Not sure what it is, so also handle it in the catch block.
throw err;
} catch (error) {
if (error instanceof Problem && error.status !== 500) {
// Handle here when not an internal error. These are mostly from buggy
// systems using API Keys, but could also be from frontend bugs. Note that
// this does not log the error (see below).
error.send(res);
} else {
// HTTP 500 Problems and all other exceptions should be handled by the
// error handler in app.js. It will log them at the ERROR level and
// include a full stack trace.
next(error);
}
}
};
2 changes: 1 addition & 1 deletion app/src/forms/common/middleware/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
...require('./dataErrors'),
...require('./errorHandler'),
...require('./rateLimiter'),
};
88 changes: 0 additions & 88 deletions app/tests/unit/forms/common/middleware/dataErrors.spec.js

This file was deleted.

Loading

0 comments on commit 2231f26

Please sign in to comment.