How to integrate KeystoneJs with Sentry.io - keystonejs

I integrated projects on other platforms with Sentry before and it is quite simple. But at this time, I'm using KeystoneJs, which is created on the top of Express.
Sentry offers this tutorial to let Express users integrate their applications with Sentry: https://sentry.io/for/express/
But it is not clear to me how to apply it on a KeystoneJs project, since we can't just invoke keystone.use()
I know we have some hooks available on keystone, so I also tried this:
const Sentry = require('#sentry/node');
Sentry.init({ dsn: 'https://a43847aba49b41d69b87793e01c008ae#sentry.io/1301672' });
keystone.set('pre:routes', Sentry.Handlers.requestHandler());
keystone.set('pre:routes', Sentry.Handlers.errorHandler());
This lead to this error:
TypeError: next is not a function
at sentryErrorMiddleware (/Users/ronconi/Workspaces/OfficePools/victoria-royals-api/src/node_modules/#sentry/node/src/handlers.ts:268:5)
at createApp (/Users/ronconi/Workspaces/OfficePools/victoria-royals-api/src/node_modules/keystone/server/createApp.js:119:29)
at Keystone.initExpressApp (/Users/ronconi/Workspaces/OfficePools/victoria-royals-api/src/node_modules/keystone/lib/core/initExpressApp.js:9:47)
at Keystone.start (/Users/ronconi/Workspaces/OfficePools/victoria-royals-api/src/node_modules/keystone/lib/core/start.js:47:7)
at Object.<anonymous> (/Users/ronconi/Workspaces/OfficePools/victoria-royals-api/src/keystone.js:69:10)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at loader (/Users/ronconi/Workspaces/OfficePools/victoria-royals-api/src/node_modules/babel-register/lib/node.js:144:5)
at Object.require.extensions.(anonymous function) [as .js] (/Users/ronconi/Workspaces/OfficePools/victoria-royals-api/src/node_modules/babel-register/lib/node.js:154:7)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at Object.<anonymous> (/Users/ronconi/Workspaces/OfficePools/victoria-royals-api/src/node_modules/babel-cli/lib/_babel-node.js:154:22)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
I'm wondering about the best way to integrate Keystone and Sentry, but I couldn't find it anywhere. If anyone made this before, please let me know!
Next thing I will try it add a separate express app to the project and link it with keystone, like described here: https://github.com/keystonejs/keystone/wiki/How-to-Add-Keystone-to-an-Already-Existing-Express-App
Since it is not exactly my case, I'm not sure if it is the best way to go or just find a way to use the regular express app.use() with KeystoneJs.

Answering my own question. No need to add a new express app for this. All I had to do was use keystone.set() instead of app.use().
Only note: When working directly with Express, you can add several error handling middlewares while with keystone, I already had something like keystone.set('500', myCustomErrorHandlingMiddleware);
So I moved the code to use sentry.Handlers.errorHandler() to inside of it.

On Keystone 6, after adding the Sentry.init call, you'll have to add two things in order to log both GraphQL errors, and errors that could come from custom endpoints.
In your keystone.ts file:
export default config({
// …
server: {
// …
// Handle express errors:
extendExpressApp: (app, createContext) => {
// Must be placed before any other middleware.
app.use(Sentry.Handler.requestHandler());
// Your other custom middlewares and controllers…
// Must be placed after every other controller.
app.use(Sentry.Handlers.errorHandler();
}
// Handle GraphQL errors
graphql: {
appolloConfig: {
plugins: [{
// Taken from https://blog.sentry.io/2020/07/22/handling-graphql-errors-using-sentry/#reporting-errors-to-sentry-with-apollo-server-nodejs-typescript
requestDidStart(_) {
return {
didEncounterErrors(ctx) {
ctx.errors.map(error => {
Sentry.withScope(scope => {
scope.setTag('kind', ctx.operation.operation);
scope.setExtra('query', ctx.request.query);
scope.setExtra('variables', ctx.request.variables);
if (error.path) {
scope.addBreadcrumb({
category: 'query-path',
message: error.path.join(' > '),
level: severityLevelFromString('debug')
});
}
Sentry.captureException(error);
});
});
}
}
}
}]
}
}
});

Related

Solidity: TypeError: Cannot read properties of undefined (reading 'JsonRpcProvider') in a simple HelloWorld contract by trying to test

I'm trying to test a simple HelloWorld.sol File:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract HelloWorld
{
function hello() public pure returns (string memory)
{
return "Hello, World";
}
}
with a HelloWorld.ts testfile
import "#nomiclabs/hardhat-ethers" ;
import { ethers } from "hardhat";
import { expect } from "chai";
describe("hello world", function()
{
it("should say hello world", async function ()
{
const HelloWorld = await ethers.getContractFactory("HelloWorld");
const hello = await HelloWorld.deploy();
expect(hello).to.equal("Hello, World");
});
});
After calling: npx hardhat test
I got result with a error message:
hello world
1) should say hello world
0 passing (78ms)
1 failing
1) hello world
should say hello world:
TypeError: Cannot read properties of undefined (reading 'JsonRpcProvider')
at Object.<anonymous> (node_modules\#nomiclabs\hardhat-ethers\src\internal\ethers-provider-wrapper.ts:4:61)
at Module._compile (node:internal/modules/cjs/loader:1218:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)
at Object.require.extensions.<computed> [as .js] (node_modules\ts-node\src\index.ts:1608:43)
at Module.load (node:internal/modules/cjs/loader:1081:32)
at Function.Module._load (node:internal/modules/cjs/loader:922:12)
at Module.require (node:internal/modules/cjs/loader:1105:19)
at require (node:internal/modules/cjs/helpers:103:18)
at Object.<anonymous> (node_modules\#nomiclabs\hardhat-ethers\src\internal\provider-proxy.ts:7:1)
at Module._compile (node:internal/modules/cjs/loader:1218:14)
I already did an internet research for answers/ fixing, but was not able to find an appropriate one..
So I don't know how to solve it and what am I supposed to do?
Thanks in advance!
please see above
Don't know why i get this error...
take a look at your contract instance, once you deploy the contract with
const hello = await HelloWorld.deploy();
You must call the hello() function to get the correct output.
Update your code with
describe("hello world", function()
{
it("should say hello world", async function ()
{
const HelloWorld = await ethers.getContractFactory("HelloWorld");
const helloWorldContract = await HelloWorld.deploy();
await helloWorldContract.deployed();
const hello = await helloWorldContract.hello();
expect(hello).to.be.equal("Hello, World");
});
});
You will notice that I also added the code await helloWorldContract.deployed(); this will wait until the deployment transaction is already on chain.
Good luck !
This error message is indicating that the JsonRpcProvider object is undefined. This error is likely being caused by an issue with the #nomiclabs/hardhat-ethers library.
A possible solution is to update the #nomiclabs/hardhat-ethers package to the latest version, as the issue may have been fixed in a newer version. You can do this by running the following command in your terminal:
npm install #nomiclabs/hardhat-ethers#latest
If updating the library doesn't resolve the issue, you could also try checking the documentation and example code provided by the library's creators, or reaching out to the library's support channels to ask for help.

angular2 testing, error in ViewUtils when using setBaseTestProviders()

When using the method 'setBaseTestProviders(..)', an error pops up in the console.
We're using angular-2.0.0-rc.1.
The test (test/areas-list.component.spec.ts) is as follows:
import {setBaseTestProviders} from "#angular/core/testing";
import {ADDITIONAL_TEST_BROWSER_PROVIDERS, TEST_BROWSER_STATIC_PLATFORM_PROVIDERS} from '#angular/platform-browser/testing/browser_static';
import {BROWSER_APP_DYNAMIC_PROVIDERS} from '#angular/platform-browser-dynamic';
setBaseTestProviders([
BROWSER_APP_DYNAMIC_PROVIDERS,
ADDITIONAL_TEST_BROWSER_PROVIDERS,
], TEST_BROWSER_STATIC_PLATFORM_PROVIDERS);
describe('test test', () => {
//Not really important
});
When I open the browser, the following error is shown in the console:
zone.js:323 Error: Error: Cannot resolve all parameters for 'ViewUtils'(RootRenderer, undefined #Inject(Token AppId), SanitizationService). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'ViewUtils' is decorated with Injectable.
at NoAnnotationError.BaseException [as constructor] (http://127.0.0.1:8080/node_modules/#angular/core/src/facade/exceptions.js:17:23)
at new NoAnnotationError (http://127.0.0.1:8080/node_modules/#angular/core/src/di/reflective_exceptions.js:217:16)
at _extractToken (http://127.0.0.1:8080/node_modules/#angular/core/src/di/reflective_provider.js:232:15)
at eval (http://127.0.0.1:8080/node_modules/#angular/core/src/di/reflective_provider.js:184:45)
at Array.map (native)
at _dependenciesFor (http://127.0.0.1:8080/node_modules/#angular/core/src/di/reflective_provider.js:184:19)
at resolveReflectiveFactory (http://127.0.0.1:8080/node_modules/#angular/core/src/di/reflective_provider.js:72:24)
at resolveReflectiveProvider (http://127.0.0.1:8080/node_modules/#angular/core/src/di/reflective_provider.js:96:97)
at Array.map (native)
at Object.resolveReflectiveProviders (http://127.0.0.1:8080/node_modules/#angular/core/src/di/reflective_provider.js:104:31)
Evaluating http://127.0.0.1:8080/test/areas-list.component.spec.js
Error loading http://127.0.0.1:8080/test/areas-list.component.spec.js
Does somebody know what the problem is? Thanks in advance!
Is there any specific case you're trying to achieve with browser static?
Here is the basic config:
import { setBaseTestProviders } from '#angular/core/testing';
import {
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS,
TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
} from '#angular/platform-browser-dynamic/testing';
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);

RN mock dismissKeyboard module

In my RN application I am importing the following module:
const dismissKeyboard = require('dismissKeyboard'); /
import dismissKeyboard from 'dismissKeyboard';
When running tests I get the following error:
Error: Cannot find module 'dismissKeyboard'
at Function.Module._resolveFilename (module.js:339:15)
at Function.Module._load (module.js:290:25)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at Object.<anonymous> (InputAccessory.js:12:25)
at Module._compile (module.js:413:34)
at loader (/Users/user/dev/app/node_modules/babel-register/lib/node.js:126:5)
I have tried with sinon:
before(() => {
sinon.stub('dismissKeyboard', () => {});
});
and also with mockey:
mockery.enable();
mockery.mock('dismissKeyboard', () => null) /
mockery.registerMock('dismissKeyboard', () => null)
But I still get the same error.
Any suggestions? The dismissKeyboard module is shipped with RN, but somehow being required separately. I am using mocha.
Update
I found that dismissKeyboard comes from
react-native/Libraries/Utilities/dismissKeyboard.js
although even using this full path when trying to mock it did not make any difference, now I am getting a warning about a module within this js file.
If you use require this can easily be mocked with mock-require. Doesn't appear to work for es6 imports though.
var mock = require('mock-require');
mock('dismissKeyboard', function () {
return 'I\'m a mocked function';
});
var dismissKeyboard = require('dismissKeyboard');
console.log(dismissKeyboard());
If you want to mock this across all your tests add it in your setup file (or create one if you haven't already) and use it when running your tests like so:
mocha --require setup.js tests

Issue integrating Jest into React application

I recently created a react application and would like to test it. I am trying to use Jest as Facebook recommends but have run into an issue. The specific error is as follows:
FAIL __tests__/popup-test.js
● Runtime Error
SyntaxError: Unexpected token [
at Function (native)
at Array.forEach (native)
at Array.forEach (native)
npm ERR! Test failed. See above for more details.
The code for popup-test.js
'use strict';
jest.unmock('../dist/test/popup.js');
const React = require('react');
const ReactDOM = require('react-dom');
const TestUtils = require('react-addons-test-utils');
let Popup = require('../dist/test/popup.js');
describe('Popup', () => {
it('works', () => {
var popupTest = TestUtils.renderIntoDocument(
<Popup />
);
var popupNode = ReactDOM.findDOMNode(popupTest);
expect(1).toEqual(1);
});
});
As you can see, the error does not provide me with any information. I know the problem is with requiring my popup file and I can post the contents of the code here. I was hoping though that someone had encountered this problem before and could guide me in the right direction to solving it.
Best,
Aneury Casado

Integrate express.js application and docpad (sharing layouts)

I'm trying to integrate one Express app with Docpad. What I want most is share layouts between my static pages and my Express views.
In the process I follow this instructions of question 16332833, with:
var docpadInstanceConfiguration = {
action: 'generate',
env: 'static'
};
require('docpad').createInstance(docpadInstanceConfiguration, function(err,docpadInstance){
if (err) return console.log(err.stack);
// ...
});
I'm getting the following error:
info: Generating...
notice: DocPad is currently running without any plugins installed. You probably want to install some: http://docpad.org/plugins
TypeError: path must be a string
at fs.exists (fs.js:166:11)
at Task.method (/Users/../node_modules/docpad/node_modules/safefs/out/lib/safefs.js:183:14)
at ambi (/Users/../node_modules/docpad/node_modules/ambi/out/lib/ambi.js:22:16)
at /Users/../node_modules/docpad/node_modules/taskgroup/out/lib/taskgroup.js:117:19
at b (domain.js:183:18)
at Domain.run (domain.js:123:23)
at Task.fire (/Users/../node_modules/docpad/node_modules/taskgroup/out/lib/taskgroup.js:116:21)
at process._tickCallback (node.js:415:13)
at Function.Module.runMain (module.js:499:11)
at startup (node.js:119:16)
at node.js:901:3
without options, and var docpadInstanceConfiguration = {}; there is no errors:
info: Welcome to DocPad v6.52.1
info: Contribute: http://docpad.org/docs/contribute
info: Plugins: cleanurls, coffeescript, downloader, eco, less, livereload, marked, partials, related, stylus, text
info: Environment: development
Any idea for getting shared layouts between docpad and express views, and get csrf protection for example? (I'm using ectjs for my views, is eco compatible)
Thanks
Turns out you need the load and ready actions prior to the generate, like so:
var docpadInstanceConfiguration = {
action: 'load ready generate',
env: 'static'
};
require('docpad').createInstance(docpadInstanceConfiguration, function(err,docpadInstance){
if (err) return console.log(err.stack);
// ...
});
However looking at the API docs it doesn't seem doing actions in this way is the right way at all, instead we should do:
var docpadInstanceConfiguration = {
env: 'static'
};
require('docpad').createInstance(docpadInstanceConfiguration, function(err,docpadInstance){
if (err) return console.log(err.stack);
var generateOpts = {};
docpadInstance.action('generate', generateOpts, function(err,result){
if (err) return console.log(err.stack);
// ...
});
});