Требуется поведение инициализации API Nodejs при использовании нескольких модулей

#javascript #node.js #firebase #google-cloud-functions #sentry

#javascript #node.js #firebase #google-cloud-функции #sentry

Вопрос:

Я использую Sentry в нескольких модулях узла. Я инициализирую его в admin.js :

 // admin.js
const Sentry = require('@sentry/node');

Sentry.init({
  dsn: functions.config().sentry.dsn,
  environment: functions.config().env.mode,
});

module.exports = { Sentry };
  

Я понимаю, что узел «требует один раз» (кэшируется после первого раза) и после этого возвращает один и тот же объект, так что несколько требований ведут себя как одно требование.

Мой вопрос касается порядка выполнения этих require инструкций и того, следует ли мне использовать опцию # 1 или # 2 ниже в других модулях (или если это вообще имеет значение):

 // utils.js
// option #1
const Sentry = require('@sentry/node');

testFn () {
  try {
    throw new Error();
  } catch (err) {
    Sentry.captureException(err);
  }
}
  
 // utils.js
// option #2
const { Sentry } = require('./admin');

testFn () {
  try {
    throw new Error();
  } catch (err) {
    Sentry.captureException(err);
  }
}
  

Если я использую вариант # 1, есть ли вероятность, что Sentry не будет должным образом инициализирован utils.js при captureException вызове?

Если оба варианта работают, является ли один предпочтительнее другого с точки зрения наилучшей практики?

Комментарии:

1. Правильным является только вариант 2. admin не импортируется в вариант 1.

2. Спасибо. Чтобы было ясно, вы говорите, что, хотя sentry инициализируется в admin.js , если используется вариант 1, sentry не будет работать в utils.js ?

3. Этого не произойдет, если admin не был импортирован до utils в модуле, который импортирует utils, и это произойдет, если admin был. Такого рода неопределенность указывает на проблему. Если utils зависит от кода от администратора и нуждается в его корректной работе, он должен импортировать его явно.

4. Это именно то, что мне нужно было знать. Это имеет смысл. Большое спасибо!

Ответ №1:

Лучше инициализировать sentry где-нибудь в корне вашего приложения, например, если вы используете express , вы могли бы инициализировать в основном server.js файл, а также может использовать промежуточные ПРОГРАММЫ, предоставляемые sentry. что-то вроде:

 const Sentry = require('@sentry/node');
const express = require('express');

Sentry.init({
  dsn: 'DSN',
  environment: 'ENV',
  release: DEPLOY_VERSION || 'n/a',
  ignoreErrors: [
    'Network request failed',
    'Failed to fetch',
    'NetworkError',
    'withrealtime/messaging',
  ],
});

// Create our express app using the port optionally specified
export const app = express();

// The request handler must be the first middleware on the app
app.use(Sentry.Handlers.requestHandler());

// The error handler must be before any other error middleware
app.use(Sentry.Handlers.errorHandler());

app.disable('x-powered-by');


app.get('/', (req, res) => {
  res.send('Hello World!')
})

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

  

Если вы хотите получать пользовательские журналы ошибок в своем приложении, вы можете поместить Sentry переменную в свою req переменную. что-то вроде:

 app.get('/', (req, res) => {
  req.sentry = Sentry;
  res.send('Hello World!')
});
  

Но это не обязательно. поскольку экземпляр sentry является общей переменной между запросами и инициализирует его один раз, он будет храниться в памяти и будет работать со всеми одновременными запросами

Комментарии:

1. Я только что добавил несколько тегов, чтобы указать, что я нахожусь в облачной среде Google Cloud. Извините, это не экспресс-приложение. То, что вы предлагаете, имеет смысл, но это не моя ситуация.