Sentry-javascript: [@ рд╕рдВрддрд░реА/рдиреЛрдб] рдПрдбрдмреНрд▓реНрдпреВрдПрд╕ рд▓реИрдореНрдмреНрдбрд╛ рдФрд░ рдЕрдиреНрдп рд╕рд░реНрд╡рд░ рд░рд╣рд┐рдд рд╕рдорд╛рдзрд╛рди рд╕рдорд░реНрдерди

рдХреЛ рдирд┐рд░реНрдорд┐рдд 28 рдЬреБрд▓ре░ 2018  ┬╖  77рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: getsentry/sentry-javascript

  • @ рд╕рдВрддрд░реА/рдиреЛрдб рд╕рдВрд╕реНрдХрд░рдг 4.0.0-рдмреАрдЯрд╛.11
  • рдореИрдВ рд╣реЛрд╕реНрдЯреЗрдб рд╕рдВрддрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдБ

рд╡рд░реНрддрдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдХреНрдпрд╛ рд╣реИ?

рдореИрдВ рдПрдбрдмреНрд▓реНрдпреВрдПрд╕ рд▓реИрдореНрдмреНрдбрд╛ рд╕рдорд╛рд░реЛрд╣ рдкрд░ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП @ рд╕рдВрддрд░реА/рдиреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдБред

    .catch(err => {
      Sentry.captureException(err)
      context.fail()
    })

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдорд╛рд░ рджреЗрддрд╛ рд╣реИ рдЬрдм context.fail() рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЕрдкрд╡рд╛рдж рд╕рдВрддрд░реА рдореЗрдВ рд╕рдорд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

рдореИрдВ рдПрдХ рдХрд╛рдордХрд╛рдЬ рдХрд░ рд╕рдХрддрд╛ рдерд╛ рдЬреИрд╕реЗ:

    .catch(err => {
      Sentry.captureException(err)
      setTimeout(() => context.fail(), 1000)
    })

рдЕрдкреЗрдХреНрд╖рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХреНрдпрд╛ рд╣реИ?

рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдореИрдВ рдХреБрдЫ рдРрд╕рд╛ рдХрд░ рд╕рдХреВрдВ:

    .catch(err => {
      Sentry.captureException(err, () => context.fail())
    })

рдпрд╛ рдХреБрдЫ рд╡рд┐рд╢реНрд╡ рд╕реНрддрд░ рдкрд░ рдХреЙрд▓рдмреИрдХ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

@LinusU рд╣рдо рдЗрд╕ рдкрд░рд┐рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рд░реНрд╡рд░ рд░рд╣рд┐рдд рдкреИрдХреЗрдЬ рдмрдирд╛рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд░рдЦрддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдмрд╕ рдХреБрдЫ рд╕рдордп рдирд┐рдХрд╛рд▓рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рд╛рд▓ рдХрд╛ рдЕрдВрдд рд╣реИ рдФрд░ рдЪреАрдЬреЗрдВ рдЕрдм рднреАрдбрд╝рднрд╛рдбрд╝ рд╡рд╛рд▓реА рд╣реЛ рд░рд╣реА рд╣реИрдВред рдЖрдкрдХреЛ рд╕реВрдЪрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд░рд╣реЗрдЧрд╛!

рд╕рднреА 77 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдпрд╣ рдореБрдЭреЗ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ https://blog.sentry.io/2018/06/20/how-droplr-uses-sentry-to-debug-serverless (рдпрд╣ рдкреБрд░рд╛рдиреЗ рд░реЗрд╡реЗрди рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдХреЙрд▓рдмреИрдХ рдерд╛, рд▓реЗрдХрд┐рди рдореИрдВ рд╣реВрдВ рдЬреНрдпрд╛рджрд╛рддрд░ рдПрдХ callbackWaitsForEmptyEventLoop рдзреНрд╡рдЬ рдХреА рдУрд░ рдЗрд╢рд╛рд░рд╛ рдХрд░рддреЗ рд╣реИрдВред

рдЕрднреА рддрдХ рдХреЛрдИ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ , рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдЕрднреА рднреА рдмреАрдЯрд╛ рдореЗрдВ рдЪреАрдЬреЛрдВ рдХреЛ рдЖрдЬрдорд╛ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдЗрд╕ рдХреЛрдб рдХреЗ рд╕рд╛рде рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╣реИ:

import { init, getDefaultHub } from '@sentry/node';

init({
  dsn: 'https://my-dsn.com/1337'
});

exports.myHandler = async function(event, context) {
  // your code

  await getDefaultHub().getClient().captureException(error, getDefaultHub().getScope());
  context.fail();
}

@kamilogorek рд╕реВрдЪрдХ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдореИрдВ рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛ рджреВрдВрдЧрд╛ рдФрд░ рд╕реАрдЦреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдЦреЗрд▓реВрдВрдЧрд╛ред

@kamilogorek рдЖрдк рд╕реБрдЭрд╛рд╡ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдореИрдВ рдПрдХ рдЕрдзрд┐рдХ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рддрд░реАрдХреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

@vietbui
4.0.0-rc.1 рдореЗрдВ рд╣рдордиреЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░ close рдирд╛рдордХ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкреЗрд╢ рдХрд┐рдпрд╛, рдЖрдк рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдХрд╣рддреЗ рд╣реИрдВ:

import { getCurrentHub } from '@sentry/node';

getCurrentHub().getClient().close(2000).then(result => {
      if (!result) {
        console.log('We reached the timeout for emptying the request buffer, still exiting now!');
      }
      global.process.exit(1);
})

close рд╕рднреА рдЕрдиреБрд░реЛрдз рднреЗрдЬреЗ рдЬрд╛рдиреЗ рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдЧрд╛, рдпрд╣ рд╣рдореЗрд╢рд╛ рд╣рд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛ (рдкрд░рд┐рдгрд╛рдо = рдЭреВрдард╛ рд╕рдордп рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ рдерд╛), рдЬрдм рддрдХ рд╕рдордп рд╕рдорд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддрд╛ (рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ 2000ms)ред
рдпрд╣ рд╣рдорд╛рд░рд╛ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдПрдкреАрдЖрдИ рд╣реИред
рдЬрдмрдХрд┐ рдкрд┐рдЫрд▓рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЕрднреА рднреА рдХрд╛рдо рдХрд░реЗрдЧрд╛, close рд╡рд┐рдзрд┐ рд╕рднреА рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддреА рд╣реИред

@HazAT рдЕрдЪреНрдЫрд╛ рд▓рдЧрд╛ред рд╕рд╛рд░реА рдХрдбрд╝реА рдореЗрд╣рдирдд рдХреЗ рд▓рд┐рдП рд╢реБрдХреНрд░рд┐рдпрд╛ред

4.0.3 рдореЗрдВ рдореИрдВ рдЗрд╕реЗ рдЕрдкрдиреЗ рд▓реИрдореНрдмреНрдбрд╛ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХрд╣рддрд╛ рд╣реВрдВ:

try {
  ...
} catch (err) {
  await getCurrentHub().getClient().captureException(err, getCurrentHub().getScope())
  throw err
}

getDefaultHub() рдЕрдм рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИред

@vietbui рдЗрд╕реЗ рдЕрдм getCurrentHub рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрдВ рдЕрдкрдиреЗ рдПрдкреАрдЖрдИ рдХреЛ рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдХреЗ рдПрд╕рдбреАрдХреЗ рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрдд рдХрд░рдирд╛ рдерд╛ред

@kamilogorek рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред getCurrentHub рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдХрд┐рд╕реА рддрд░рд╣ рдореИрдВрдиреЗ рдЬреЛ рджрд╛рдпрд░рд╛ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рд╣реИ рд╡рд╣ рд╕рдВрддрд░реА рдореЗрдВ рд╕рдорд╛рдкреНрдд рдирд╣реАрдВ рд╣реБрдЖред

рдЕрдВрдд рдореЗрдВ рдореИрдВрдиреЗ рдЕрдкрдиреЗ рд▓реИрдореНрдмреНрдбрд╛ рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП @HazAT рджреНрд╡рд╛рд░рд╛ рд╕реБрдЭрд╛рдП рдЧрдП рдЕрдиреБрд╕рд╛рд░ рдПрдХ рдЕрд▓рдЧ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд▓рд┐рдпрд╛:

try {
  ...
} catch (err) {
  Sentry.captureException(err)
  await new Promise(resolve => Sentry.getCurrentHub().getClient().close(2000).then(resolve))
  throw err
}

рдФрд░ рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдХреНрдпрд╛ рдШрдЯрдирд╛рдУрдВ рдХреЛ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрддрд░реА рдХреЛ рдкреНрд░рддреАрдХреНрд╖рд╛/рдордЬрдмреВрд░ рдХрд░рдиреЗ рдХрд╛ рдпрд╣ рдЕрдиреБрд╢рдВрд╕рд┐рдд рддрд░реАрдХрд╛ рд╣реИ?

@albinekb рд╣рд╛рдБ - https://docs.sentry.io/learn/draining/?platform=browser

рдпрд╣ рд╕рдорд╛рдзрд╛рди рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ рдкрд╣рд▓реА рдмрд╛рд░ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬрдм рдардВрдб рд╢реБрд░реВ рд╣реЛрдиреЗ рдХрд╛ рд╕рдордп рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдЙрджрд╛рд╣рд░рдг рдХреЛрдб рд╣реИ

'use strict'

const Sentry =  require('@sentry/node')
Sentry.init({
  dsn: 'xxx',
  environment: process.env.STAGE
});

module.exports.createPlaylist = async (event, context, callback) => {
  context.callbackWaitsForEmptyEventLoop = false
  if(!event.body) {
    Sentry.captureException(error)
    await new Promise(resolve => Sentry.getCurrentHub().getClient().close(2000).then(resolve))
    return {
      statusCode: 500,
      headers: { 'Content-Type': 'text/plain' },
      body: 'Missing body parameters'
    }
  }
  return {
    statusCode: 200,
  }
};

@ рдПрдВрдбреНрд░реА-рдХреБрд▓рдХ рдиреЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдореЗрдВ рднреА рдХрд╣рд╛ рд╣реИ:

After shutdown the client cannot be used any more so make sure to only do that right before you shut down the application.

рддреЛ рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рд╣рдо рдЗрд╕реЗ рд▓реИрдореНрдмреНрдбрд╛ рдореЗрдВ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рд╣рдо рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ рдЖрд╡реЗрджрди рдХрдм рдорд╛рд░рд╛ рдЬрд╛рдПрдЧрд╛ред рдкреНрд░рддрд┐ рдЕрдиреБрд░реЛрдз рд╕рдВрддрд░реА рдХреЛ рдирд┐рдХрд╛рд▓рдирд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдЬреИрд╕реЗ рд╣рдо рдкреБрд░рд╛рдиреЗ рдПрдкреАрдЖрдИ рдХреЗ рд╕рд╛рде рдХрд░ рд╕рдХрддреЗ рдереЗ?

@HazAT рдХреНрдпрд╛ рд╣рдо рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓ рд╕рдХрддреЗ рд╣реИрдВ? рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд▓реИрдореНрдмреНрдбрд╛ рдкрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реЛрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рдЬреЛ рдХрд┐ рддреИрдирд╛рддреА рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрдо рд▓рдХреНрд╖реНрдп рдмрдирддрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред

рдпрд╣ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдореБрдЭреЗ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХ рд░рд╣рд╛ рд╣реИ...

рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ, рдореИрдВ рдХрд┐рд╕реА рддреНрд░реБрдЯрд┐ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рддреЗ рд╕рдордп рдПрдХ рд╡рд╛рджрд╛/рдХреЙрд▓рдмреИрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛ред рдХрддрд╛рд░ рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╛рдж рдореЗрдВ рдмрдВрдж рдХрд┐рдП рдмрд┐рдирд╛ рдирд┐рдХрд╛рд▓рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реЛрдирд╛ рдЕрдЧрд▓реА рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рдмрд╛рдд рд╣реЛрдЧреА ...

рдХреЙрд▓рдмреИрдХ рдХреЛ captureException рд╕реЗ рд╣рдЯрд╛рдиреЗ рдХрд╛ рдФрдЪрд┐рддреНрдп рдХреНрдпрд╛ рдерд╛?

@albinekb рдЕрдЧрд░ рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрдВрдХреНрддрд┐ рдХреЛ рд╣рдЯрд╛рддрд╛ рд╣реВрдВ рддреЛ рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ

await new Promise(resolve => Sentry.getCurrentHub().getClient().close(2000).then(resolve))

@LinusU рдХреНрдпрд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ рдФрд░ рд╕рдВрддрд░реА рдпрд╛ рд░реЗрд╡реЗрди рд╕рдорд╛рдзрд╛рди рдХреНрдпрд╛ рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ?

рдореЗрд░реЗ рд▓рд┐рдП рдореВрд▓ рд░реВрдк рд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ sentry/node @4.3.0 , рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓реИрдореНрдмреНрдбрд╛ рдХреЛ рдХреБрдЫ рд╕рдордп рдХреЗ рд▓рд┐рдП рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреА рд╣реЛрдЧреА (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдореИрдВ 2 рд╕реЗрдХрдВрдб рд▓рдЧрд╛рддрд╛ рд╣реВрдВ) рд╕рдВрддрд░реА рдХреЛ рд╡рд╣ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛ рдЙрд╕реЗ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЬреЛ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЗрд╕реЗ рд╡рд╣рд╛рдВ рдХреНрдпреЛрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рд╣рдо captureException рдЕрдиреБрд░реЛрдз рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрддрд░реА рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЕрдЧрд░ рдореЗрд░реЗ рдкрд╛рд╕ рдмрд╛рдж рдореЗрдВ рдкреНрд░рддреАрдХреНрд╖рд╛ рдЕрд╡рдзрд┐ рдирд╣реАрдВ рд╣реИ, рддреЛ рд╕рдВрддрд░реА рддреНрд░реБрдЯрд┐ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреАрдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

'use strict'

const Sentry =  require('@sentry/node')
Sentry.init({
  dsn: 'xxx',
  environment: process.env.STAGE
});

module.exports.createPlaylist = async (event, context, callback) => {
  context.callbackWaitsForEmptyEventLoop = false
  if(!event.body) {
    const error = new Error('Missing body parameters in createPlaylist')
    await Sentry.captureException(error)
    await new Promise(resolve => {setTimeout(resolve, 2000)})
    return {
      statusCode: 500,
      headers: { 'Content-Type': 'text/plain' },
      body: 'Missing body parameters'
    }
  }
  return {
    statusCode: 200,
  }
};

рд╣рдо рд▓реИрдореНрдмреНрдбрд╛ рдкрд░ рднреА рдЗрд╕ рдкрд░ рдЬрд▓ рд░рд╣реЗ рд╣реИрдВред рд╣рдордиреЗ рдирдП рдХрд╛рдореЛрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реБрдЖрдд рдХреА рдФрд░ рд░реЗрд╡реЗрди рдкрд░ рд╡рд╛рдкрд╕ рдЬрд╛рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реБрдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдмреЙрдХреНрд╕рд┐рдВрдЧ рдЖрдЙрдЯ рд╣реЛ рдЧрдПред рд╣рдм рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдФрд░ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдкреНрд░рдпрд╛рд╕ рдХреЗ рд▓рд┐рдП рд╣рдо рдЕрднреА рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВ, рдЬреЛ рдкрд╛рдиреА рд░рдЦрдиреЗ рдкрд░ рдПрдХ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╕рдорд╛рдзрд╛рди рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдЕрднреА рднреА рд╣реИрдХреА/рд▓реЛрдб рдХреЗ рддрд╣рдд рд╕рдорд╕реНрдпрд╛рдПрдВ рдкреИрджрд╛ рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИред

рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдореИрдВ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ flush() рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛ рдЬреЛ рдПрдХ рд╡рд╛рджрд╛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ - рдПрдХ рдирдХрд╛рд░рд╛рддреНрдордХ рдкрдХреНрд╖ рдЦреЛрдЬрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рд╕реЛрдЪреЛ рдРрд╕рд╛ рдХрднреА рд╣реЛрдЧрд╛?

рд╕рдорд╛рдзрд╛рди рдХреНрдпрд╛ рд╣реИ рдФрд░ рд╕рдВрддрд░реА рдпрд╛ рд░реЗрд╡реЗрди рд╕рдорд╛рдзрд╛рди рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ?

рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрдХреНрд╕рдкреНрд░реЗрд╕ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ:

app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
  let status = (err.status || err.statusCode || 500) as number

  if (process.env.NODE_ENV === 'test') {
    return next(err)
  }

  if (status < 400 || status >= 500) {
    Raven.captureException(err, () => next(err))
  } else {
    next(err)
  }
})

рдореИрдВ рддрдм рд▓реИрдореНрдмреНрдбрд╛ рдореЗрдВ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рдРрдк рдХреЛ рддреИрдирд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдХреИрдВрдбрд┐рдпрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдпрд╣ рд░реЗрд╡реЗрди рдХреЗ рд╕рд╛рде рд╣реИ "raven": "^2.6.3",

рдбреНрд░реАрдо рдПрдкреАрдЖрдИ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛

Sentry.captureException(err: Error): Promise<void>

@LinusU https://github.com/getsentry/sentry-javascript/blob/master/packages/core/src/baseclient.ts#L145 -L152

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рд╕реАрдзреЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рдХрд╛ рдХрд╛рд░рдг рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рддрдп рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдореБрдЦреНрдп рдкрд░рд┐рджреГрд╢реНрдп "рдЖрдЧ рдФрд░ рднреВрд▓" рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реИ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдпрд╣ рдПрдХ рдПрд╕рд┐рдВрдХ рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реИред рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрд╕рд┐рдВрдХ рдПрдкреАрдЖрдИ рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╣рдо рд╕реНрд╡рдпрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЬреЛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рд╡рд╣ рдХреБрдЫ рдФрд░ рд╣реИ:

const backend = client.getBackend()
const event = await backend.eventFromException(error)
await client.processEvent(event, finalEvent => backend.sendEvent(finalEvent))

рд╕рднреА рдХрддрд╛рд░рдмрджреНрдз рдФрд░ рдмрдлрд╝рд░рд┐рдВрдЧ рдХреЛ рдЫреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП...

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдбрд┐рдЬрд╛рдЗрди "рдЖрдЧ рдФрд░ рднреВрд▓" рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИ, рдФрд░ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рд╕рд░реНрд╡рд░ рдореЗрдВ рдЪрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ рдпрд╣ рд╢рд╛рдпрдж рдЙрд╕ рдкрд░ рдХрд╛рдлреА рдЕрдЪреНрдЫрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдмрдлрд░рд┐рдВрдЧ рдХрд░рддрд╛ рд╣реИред рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рд╡рд┐рдкрд░реАрдд рд╣реИ рдХрд┐ рдЖрдк рд▓реИрдореНрдмреНрдбрд╛, рдРрдк рдЗрдВрдЬрди рдФрд░ рдЕрдиреНрдп "рд╕рд░реНрд╡рд░ рд░рд╣рд┐рдд" рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд▓рд┐рдП рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬреЛ рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рд╣реЛрддреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВред

рдХреНрдпрд╛ рдпрд╣ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ рдХрд┐ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╡рд┐рдзрд┐ рд╣реЛ рдЬреЛ рдШрдЯрдирд╛ рдХреЛ рдЬрд┐рддрдиреА рдЬрд▓реНрджреА рд╣реЛ рд╕рдХреЗ рднреЗрдЬ рджреЗ, рдФрд░ рдПрдХ Promise рд▓реМрдЯрд╛рдП рдЬрд┐рд╕реЗ рд╣рдо await рдХрд░ рд╕рдХреЗрдВ? рдпрд╣ рд╕рд░реНрд╡рд░ рд░рд╣рд┐рдд рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХрджрдо рд╕рд╣реА рд╣реЛрдЧрд╛!

class Sentry {
  // ...

  async unbufferedCaptureException(err: Error): Promise<void> {
    const backend = this.client.getBackend()
    const event = await backend.eventFromException(error)
    await this.client.processEvent(event, finalEvent => backend.sendEvent(finalEvent))
  }

  // ...
}

@LinusU рд╣рдо рдЗрд╕ рдкрд░рд┐рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рд░реНрд╡рд░ рд░рд╣рд┐рдд рдкреИрдХреЗрдЬ рдмрдирд╛рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд░рдЦрддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдмрд╕ рдХреБрдЫ рд╕рдордп рдирд┐рдХрд╛рд▓рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рд╛рд▓ рдХрд╛ рдЕрдВрдд рд╣реИ рдФрд░ рдЪреАрдЬреЗрдВ рдЕрдм рднреАрдбрд╝рднрд╛рдбрд╝ рд╡рд╛рд▓реА рд╣реЛ рд░рд╣реА рд╣реИрдВред рдЖрдкрдХреЛ рд╕реВрдЪрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд░рд╣реЗрдЧрд╛!

рд╣рдо рдЗрд╕ рдкрд░рд┐рджреГрд╢реНрдп рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рд░реНрд╡рд░ рд░рд╣рд┐рдд рдкреИрдХреЗрдЬ рдмрдирд╛рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд░рдЦрддреЗ рд╣реИрдВ

рд╡рд╣ рдЕрджреНрднреБрдд рд╣реЛрдЧрд╛! рдореИрдВ

@mtford90

рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рдмреЗрд╣рддрд░ рд╕рдорд╛рдзрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрдм рдХрд░реВрдВрдЧрд╛? рдЬрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЬрд╛рдирдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд▓реИрдореНрдмреНрдбрд╛ рдХрдм рдмрдВрдж рд╣реЛ рдЬрд╛рдПрдЧрд╛ - рд╕рд╛рде рд╣реА рд╕рдВрддрд░реА рдХреЛ рдЕрдкрдиреА рдмрд╛рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рд╢рдЯрдбрд╛рдЙрди рдХреЗ рд▓рд┐рдП рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рд╕рдордп рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдирд╛ рдореВрд░реНрдЦрддрд╛рдкреВрд░реНрдг рд▓рдЧрддрд╛ рд╣реИ - рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдорд╣рдВрдЧреА рдЙрдЪреНрдЪ рдореЗрдореЛрд░реА/рд╕реАрдкреАрдпреВ рд▓реИрдореНрдмреНрдбрд╛ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдкрд░ред

(рдЬрд▓ рдирд┐рдХрд╛рд╕реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ)

рдпрд╣ рд╕рд░реНрд╡рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЖрдЦрд┐рд░реА рдЪреАрдЬ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИред drain рдкрджреНрдзрддрд┐ рдореЗрдВ рд╕рдордпрдмрд╛рд╣реНрдп рд╡рд╣ рдЕрдзрд┐рдХрддрдо рд╕рдордп рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╣рдо рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВрдЧреЗ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рдпрд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╣рдо рд╣рдореЗрд╢рд╛ рдЙрд╕ рд╕рдордп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдпрджрд┐ рд╕рд░реНрд╡рд░ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рд╣реИ, рддреЛ рдпрд╣ рд╢реЗрд╖ рд╕рднреА рдИрд╡реЗрдВрдЯ рдХреЛ рддреБрд░рдВрдд рднреЗрдЬ рджреЗрдЧрд╛ред

рдЗрд╕реЗ рдкреНрд░рддрд┐ рд╕реЗ рдЬрд╛рдирдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд▓реИрдореНрдмреНрдбрд╛ рдХреЛ рдпрд╣ рдмрддрд╛рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рд╣реИрдВрдбрд▓рд░ рдХреЗ рдХреЙрд▓рдмреИрдХ рддрд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрдм рдмрдВрдж рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ @LinusU , рдореИрдВрдиреЗ рдЖрдкрдХреА рдкрд┐рдЫрд▓реА рдЯрд┐рдкреНрдкрдгреА, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЗрд╕ рднрд╛рдЧ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрдврд╝рд╛:

рдХреНрдпрд╛ рдпрд╣ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ рдХрд┐ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╡рд┐рдзрд┐ рд╣реЛ рдЬреЛ рдШрдЯрдирд╛ рдХреЛ рдЬрд┐рддрдиреА рдЬрд▓реНрджреА рд╣реЛ рд╕рдХреЗ рднреЗрдЬ рджреЗ, рдФрд░ рдПрдХ рд╡рд╛рджрд╛ рд▓реМрдЯрд╛рдП рдЬрд┐рд╕рдХрд╛ рд╣рдо рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдпрд╣ рд╕рд░реНрд╡рд░ рд░рд╣рд┐рдд рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХрджрдо рд╕рд╣реА рд╣реЛрдЧрд╛!

рдЗрд╕ рддрд░рд╣ рд╣рдордиреЗ рдЕрдкрдиреЗ рдмрдлрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ред рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░ рдкреНрд░рддреНрдпреЗрдХ captureX рдХреЙрд▓, рдЗрд╕реЗ рдмрдлрд░ рдореЗрдВ рдЬреЛрдбрд╝ рджреЗрдЧрд╛, рдпрд╣ рд╕рд╣реА рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдХрддрд╛рд░рдмрджреНрдз рдирд╣реАрдВ рд╣реИ, рдЗрд╕реЗ рддреБрд░рдВрдд рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рдЗрд╕рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╣рдо рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХреЗрдВ рдпрджрд┐ рд╕рдм рдХреБрдЫ рдерд╛ рд╕рдВрддрд░реА рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рднреЗрдЬрд╛ рдЧрдпрд╛ред

https://github.com/getsentry/sentry-javascript/blob/0f0dc37a4276aa2b832da451307bc4cd5413b34d/packages/core/src/requestbuffer.ts#L12 -L18

рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк AWS рд▓реИрдореНрдмреНрдбрд╛ рдореЗрдВ рдРрд╕рд╛ рдХреБрдЫ рдХрд░рддреЗ рд╣реИрдВ (рдпрд╣ рдорд╛рдирддреЗ рд╣реБрдП рдХрд┐ рдЖрдк рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХреНрд▓рд╛рдЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬреЛ рдХрд┐ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдорд╛рдорд▓рд╛ рд╣реИ):

import * as Sentry from '@sentry/browser';

Sentry.init({ dsn: '__YOUR_DSN__' });

exports.handler = (event, context, callback) => {
    try {
      // do something
    catch (err) {
      Sentry.getCurrentHub()
        .getClient()
        .captureException(err)
        .then((status) => {
          // request status
          callback(null, 'Hello from Lambda');
        })
    }
};

рдЖрдк рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕реЗ рддреБрд░рдВрдд рднреЗрдЬ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдХреЛрдИ рд╕рдордп/рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдУрд╡рд░рд╣реЗрдб рдирд╣реАрдВ рдерд╛ред

@ рдХрд╛рдорд┐рд▓реЛрдЧреЛрд░реЗрдХ
рдХреНрдпрд╛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдРрд╕рд╛ рдХреБрдЫ рдПрд╕рд┐рдВрдХ/рдкреНрд░рддреАрдХреНрд╖рд╛ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП (рдЬрд╣рд╛рдВ рдЖрдк рдХреЙрд▓рдмреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ)?

import * as Sentry from '@sentry/node';

Sentry.init({ dsn: '__YOUR_DSN__' });

exports.handler = async (event, context) => {
    try {
      // do something

      return 'Hello from Lambda';
    catch (err) {
      await Sentry.getCurrentHub().getClient().captureException(err);
      return 'Hello from Lambda with error';
    }
};

@jviolas рдкреВрд░реА рддрд░рд╣ рд╕реЗ! :)

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░рд┐рд╡рд░реНрддрди рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ рддреЛ тШ║я╕П

-import Raven = require('raven')
+import * as Sentry from '@sentry/node'

 // ...

-Raven.config(config.SENTRY_DSN)
+Sentry.init({ dsn: config.SENTRY_DSN })

 // ...

 app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
   let status = (err.status || err.statusCode || 500) as number

   if (process.env.NODE_ENV === 'test') {
     return next(err)
   }

   if (status < 400 || status >= 500) {
-    Raven.captureException(err, () => next(err))
+    Sentry.getCurrentHub().getClient().captureException(err).then(() => next(err))
   } else {
     next(err)
   }
 })

рд╕рдЪ рдХрд╣реВрдВ, рддреЛ рд╣рд░ рд▓рд╛рдЗрди рдереЛрдбрд╝реА рдмрджрд╕реВрд░рдд рд╣реЛ рдЧрдИ ЁЯШЖ рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╣реБрдб рдХреЗ рдиреАрдЪреЗ рдмреЗрд╣рддрд░ рд╣реИ ...

@kamilogorek рдореБрдЭреЗ рдЖрдкрдХреА рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдореЗрдВ getCurrentHub() рдирд╣реАрдВ рдорд┐рд▓рд╛, рдХреНрдпрд╛ рдпрд╣ рдПрдкреАрдЖрдИ рдЧрд╛рд░рдВрдЯреА рд╣реИ рдХрд┐ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдмрдбрд╝реЗ рд╕реЗрдорд░ рдЯрдХреНрдХрд░ рдХреЗ рдЯреВрдЯрдиреЗ рдХреА рдЧрд╛рд░рдВрдЯреА рд╣реИ? тЭдя╕П

@kamilogorek рдореБрдЭреЗ рдЖрдкрдХреА рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдореЗрдВ getCurrentHub() рдирд╣реАрдВ рдорд┐рд▓рд╛, рдХреНрдпрд╛ рдпрд╣ рдПрдкреАрдЖрдИ рдЧрд╛рд░рдВрдЯреА рд╣реИ рдХрд┐ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдмрдбрд╝реЗ рд╕реЗрдорд░ рдЯрдХреНрдХрд░ рдХреЗ рдЯреВрдЯрдиреЗ рдХреА рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рд╣реИ? тЭдя╕П

рд╣рд╛рдБ, рдЗрд╕рдХреА рдЧрд╛рд░рдВрдЯреА рд╣реИред рдпрд╣ @sentry/hub рдкреИрдХреЗрдЬ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╡рд░реНрдгрди рдпрд╣рд╛рдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ - https://docs.sentry.io/enriching-error-data/scopes/?platform=browser

рд╣рдо рдпрд╣рд╛рдВ рдЗрд╕ рд╕реВрддреНрд░ рдореЗрдВ рдереЛрдбрд╝реЗ "рдЙрдиреНрдирдд рдЙрдкрдпреЛрдЧреЛрдВ" рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдФрд░ рд╣рдо рдЕрднреА рддрдХ рдЙрдиреНрд╣реЗрдВ рджрд╕реНрддрд╛рд╡реЗрдЬ рдХрд░рдиреЗ рдХреЗ рдмрд┐рдВрджреБ рдкрд░ рдирд╣реАрдВ рдкрд╣реБрдВрдЪреЗ рд╣реИрдВред рд╣рдо рдЗрд╕реЗ рдЕрдВрддрддрдГ рдХрд░реЗрдВрдЧреЗ :)

рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╣рдо рдпрд╣рд╛рдВ рдЬреЛ рдХреБрдЫ рдЦреЛ рд░рд╣реЗ рд╣реИрдВ рд╡рд╣ рд╣реИ рдЗрд╕ рддрд░рд╣ рдХреЗ рдЙрдиреНрдирдд рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдХреБрдЫ рджрд╕реНрддрд╛рд╡реЗрдЬ рдФрд░ рдЕрдЪреНрдЫрд╛ рдЕрднреНрдпрд╛рд╕ред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдЬрдм рдЗрд╕реЗ рдкреНрд░рд▓реЗрдЦрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рдмреНрд▓реЙрдЧ рдкреЛрд╕реНрдЯ рднреА рдПрдХ рдЕрдЪреНрдЫреА рд╢реБрд░реБрдЖрдд рд╣реЛ рд╕рдХрддреА рд╣реИред
рдЕрдиреНрдпрдерд╛, рдирдпрд╛ рдПрд╕рдбреАрдХреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдореЗрдВ рдЖрд╕рд╛рди рд╣реИ рдФрд░ рдПрдХреАрдХрд░рдг рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдЪреНрдЫрд╛ рд╣реИред

@ рдХрд╛рдорд┐рд▓реЛрдЧреЛрд░реЗрдХ
рдХреНрдпрд╛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдРрд╕рд╛ рдХреБрдЫ рдПрд╕рд┐рдВрдХ/рдкреНрд░рддреАрдХреНрд╖рд╛ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП (рдЬрд╣рд╛рдВ рдЖрдк рдХреЙрд▓рдмреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ)?

import * as Sentry from '@sentry/node';

Sentry.init({ dsn: '__YOUR_DSN__' });

exports.handler = async (event, context) => {
    try {
      // do something

      return 'Hello from Lambda';
    catch (err) {
      await Sentry.getCurrentHub().getClient().captureException(err);
      return 'Hello from Lambda with error';
    }
};

рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреБрдЫ рдХрд░рдирд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рдореИрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдВрджрд░реНрдн рдЬреЛрдбрд╝рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрде рд╣реВрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдореИрдВ рдХрд░рддрд╛ рд╣реВрдВ:

Sentry.configureScope(scope => {
   scope.setExtra('someExtraInformation', information);
});
await Sentry.getCurrentHub().getClient().captureException(err);

рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдВрддрд░реА рдореЗрдВ 'someExtraInformation' рдирд╣реАрдВ рджреЗрдЦреВрдВрдЧрд╛ред

рдХрд┐рд╕реА рдиреЗ рдЗрд╕ рдзрд╛рдЧреЗ рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╡рд┐рдзрд┐ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдерд╛, рдФрд░ рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣реИрдХреА рд▓рдЧрддрд╛ рд╣реИ (рдПрдХ рдЯрд╛рдЗрдордЖрдЙрдЯ рдХреЛ рдордЬрдмреВрд░ рдХрд░рдирд╛)ред

Sentry.configureScope(scope => {
  scope.setExtra('someExtraInformation', information);
});
Sentry.captureException(error);
await new Promise(resolve => Sentry.getCurrentHub().getClient().close(2000).then(resolve));

@kamilogorek @jviolas

import * as Sentry from '@sentry/node';

Sentry.init({ dsn: '__YOUR_DSN__' });

exports.handler = async (event, context) => {
   try {
     // do something

     return 'Hello from Lambda';
   catch (err) {
     await Sentry.getCurrentHub().getClient().captureException(err);
     return 'Hello from Lambda with error';
   }
};

рдХреНрдпрд╛ рдЗрд╕реЗ _рдЕрдирдХреЙрдЯреЗрдб рдЕрдкрд╡рд╛рдж_ рдкрд░ рднреА рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ? рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ Sentry.Integrations.OnUncaughtException рдПрдХреАрдХрд░рдг рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдирд╛ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рддрд░реАрдХрд╛ рд╣реИ рд▓реЗрдХрд┐рди рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдЕрднреА рдмрд╣реБрдд рдЦрд░рд╛рдм рд╣реИред

рдЗрд╕рдХреЗ рд▓рд┐рдП +1ред рдХрдо рд╕реЗ рдХрдо рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рддреМрд░ рдкрд░ рдХреБрдЫ рдкреНрд░рд▓реЗрдЦрд┐рдд рд╣реЛрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред 2019 рддрдХ рд╕рд░реНрд╡рд░ рд░рд╣рд┐рдд рддреЗрдЬреА рд╕реЗ рдмрдврд╝ рд░рд╣рд╛ рд╣реИ, рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рдкрд░ рд╕рдВрддрд░реА рд╕реЗ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рд╕рдорд░реНрдерди рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдЬрд┐рди рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЛ рдореИрдВрдиреЗ рдпрд╣рд╛рдВ рдкрдврд╝рд╛ рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд╕рдВрдж рдХрд┐рдпрд╛ рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рдпрд╣ рдерд╛ рдХрд┐ рдХрддрд╛рд░рдмрджреНрдз рд╕рднреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП Sentry.flush() рдЬреИрд╕рд╛ рдХреБрдЫ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

@rdsedmundo рдХреНрдпрд╛ рдЖрдк рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдмрддрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЖрдкрдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ?

import * as Sentry from '@sentry/node';

Sentry.getCurrentHub().getClient().close(2000).then(result => {
      if (!result) {
        console.log('We reached the timeout for emptying the request buffer, still exiting now!');
      }
      global.process.exit(1);
})

рдпрд╣ рд╣рдорд╛рд░рд╛ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИ рдФрд░ рдореВрд▓ рд░реВрдк рд╕реЗ Sentry.flush() рд╣реИред
рд╕рдВрджрд░реНрдн: https://docs.sentry.io/error-reporting/configuration/draining/?platform=javascript

@HazAT рдЗрд╕рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рддрдм рдЖрддреА рд╣реИ рдЬрдм рдЖрдк AWS рд▓реИрдореНрдмреНрдбрд╛ рдХрдВрдЯреЗрдирд░ рдХреЗ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрддреЗ рд╣реИрдВред рдЬреЛ рдЯреАрдПрд▓; рдбреАрдЖрд░ рд╢рдмреНрджреЛрдВ рдореЗрдВ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдПрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЬрд┐рд╕рдиреЗ рдЕрднреА-рдЕрднреА рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рд╣реИ, рд╡рд╣ рдПрдХ рдирдП рдмреНрд░рд╛рдВрдб рдХреА рд╕реЗрд╡рд╛ рдХрд░ рд╕рдХрддреА рд╣реИ рдпрджрд┐ рдпрд╣ рд╕рдордп рдХреА рдПрдХ рдЫреЛрдЯреА рдЦрд┐рдбрд╝рдХреА рдкрд░ рдмрдирд╛рдИ рдЧрдИ рд╣реЛред рдЕрдЧрд░ рдореИрдВ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рджрд┐рдП рдЧрдП рдЗрд╕ рд╕реНрдирд┐рдкреЗрдЯ рдХреЗ рд╕рд╛рде рдХрдиреЗрдХреНрд╢рди рдмрдВрдж рдХрд░ рджреВрдВ, рдФрд░ рдХрдВрдЯреЗрдирд░ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдП, рддреЛ рдореБрдЭреЗ рдирдП рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рд╣рдм рдмрдирд╛рдиреЗ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдореИрдВ рдЗрд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛрддреЗ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реВрдВред рдЗрд╕рд▓рд┐рдП рдПрдХ рд╕рд╛рдзрд╛рд░рдг await Sentry.flush() рдПрдХ рдмреЗрд╣рддрд░ рдЙрдкрд╛рдп рд╣реЛрдЧрд╛:

import Sentry from './sentry'; // this calls Sentry.init under the hood

export const handler = async (event, context) => {
  try {
    ...
  } catch (error) {
    Sentry.captureException(error);
    await Sentry.flush(); // could even be called on the finally block

    return formatError(error);
  }
}

@rdsedmundo рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореИрдВ рд╢рд╛рдпрдж рдХреБрдЫ рдЧрд▓рдд рд╕рдордЭ рд░рд╣рд╛ рд╣реВрдВ рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдХрд░рддреЗ рд╣реИрдВ

import Sentry from './sentry'; // this calls Sentry.init under the hood

export const handler = async (event, context) => {
  try {
    ...
  } catch (error) {
    Sentry.captureException(error);
    await Sentry.getCurrentHub().getClient().close(2000);

    return formatError(error);
  }
}

рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ await Sentry.flush рдЬреИрд╕рд╛ рд╣реА рд╣реИ рдХрд┐ рдЖрдк рдЯрд╛рдЗрдордЖрдЙрдЯ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред

рд╡рд╛рджрд╛ 2000ms рдХреЗ рдмрд╛рдж рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ false рдХреЗ рд╕рд╛рде рд╣рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдпрджрд┐ рдХрддрд╛рд░ рдореЗрдВ рдЕрднреА рднреА рд╕рд╛рдорд╛рди рдерд╛ред
рдЕрдиреНрдпрдерд╛ close true рдХреЗ рд╕рд╛рде рд╣рд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдпрджрд┐ рд╕рдордп рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХрддрд╛рд░ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдпрд╛ рд╕рднреА рд╡рд╛рджреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХрдВрдЯреЗрдирд░ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛? (рдореИрдВ рдЗрд╕рдХреА рдХрд▓реНрдкрдирд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛)

@HazAT рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ close(...) рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХреЗрдЧрд╛? рд▓реИрдореНрдмреНрдбрд╛ рдЙрд╕реА рдиреЛрдб рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдХреЙрд▓ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧреА, рдЬреЛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдкрд╣рд▓реА рдХреЙрд▓ рдХреЗ рдмрд╛рдж close рдкрд░ рдХрд╛рдо рдХрд░рдирд╛ рдмрдВрдж рдХрд░ рджреЗрдЧрд╛?

  • Sentry.init()
  • Sentry.captureException()
  • Sentry.getCurrentHub().getClient().close()
  • Sentry.captureException()
  • Sentry.getCurrentHub().getClient().close()
  • Sentry.captureException()
  • Sentry.getCurrentHub().getClient().close()
  • Sentry.captureException()
  • Sentry.getCurrentHub().getClient().close()
  • ...

рдирд╣реАрдВ, close рдЧреНрд░рд╛рд╣рдХ рдХрд╛ рдирд┐рдкрдЯрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдпрд╣ рд╕рд┐рд░реНрдл рдкрд░рд┐рд╡рд╣рди рдХрддрд╛рд░ рдХреЛ рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИред
рдореИрдВ рдорд╛рдирддрд╛ рд╣реВрдВ рдХрд┐ рдЗрд╕ рд╕рдВрджрд░реНрдн рдореЗрдВ рдирд╛рдо close рднреНрд░рд╛рдордХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдХрдо рд╕реЗ рдХрдо JS/Node рдореЗрдВ close рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рд╕рд╛рде рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдмрд╛рдж рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдареАрдХ рд╣реИред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдпрджрд┐ рд╡рд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ "рдореБрджреНрджрд╛" рдерд╛ рддреЛ рдореИрдВ рдЗрд╕реЗ рд╕реНрдкрд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░ рджреВрдВрдЧрд╛ред

рдардВрдбрд╛ред рд▓реЗрдХрд┐рди рджрд╕реНрддрд╛рд╡реЗрдЬ рддрдм рдЧрд▓рдд рд╣реИ:

After shutdown the client cannot be used any more so make sure to only do that right before you shut down the application.

рдареАрдХ рд╣реИ, рд╣рдордиреЗ рдЕрднреА рдЗрд╕ рдорд╛рдорд▓реЗ рдкрд░ рдЯреАрдо рдореЗрдВ рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ рдЪрд░реНрдЪрд╛ рдХреА рд╣реИред
рдЖрдк рд▓реЛрдЧ рд╕рд╣реА рдереЗ рдФрд░ рдЬрдмрдХрд┐ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЕрднреА рдЙрд╕ рддрд░рд╣ рд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдЬреИрд╕рд╛ рд╣рдордиреЗ рдЗрд╕реЗ рдкреНрд░рд▓реЗрдЦрд┐рдд рдХрд┐рдпрд╛ рд╣реИ рд╣рдо рдПрдХ flush рдлрд╝рдВрдХреНрд╢рди рдкреЗрд╢ рдХрд░реЗрдВрдЧреЗ рдЬреЛ рдареАрдХ рд╡рд╣реА рдХрд░реЗрдЧрд╛ рдЬреЛ рдЖрдк рдЙрдореНрдореАрдж рдХрд░рддреЗ рд╣реИрдВред

рддреЛ рдЕрднреА рдЖрдк рдмрд┐рдирд╛ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЗ close рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╣рдо рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЧреНрд░рд╛рд╣рдХ рдХреЛ рдирд┐рдкрдЯрд╛рдиреЗ/рдЕрдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдмрджрд▓рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ)ред
рд▓реЗрдХрд┐рди рдПрдХ flush рдлрд╝рдВрдХреНрд╢рди рд╣реЛрдЧрд╛ рдЬреЛ _just_ flush рдХрддрд╛рд░ рдореЗрдВ рд╣реИред

рдлреАрдЪрд░ рдЖрдиреЗ рдХреЗ рдмрд╛рдж рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░ рджреВрдВрдЧрд╛ред

рдЪреВрдВрдХрд┐ рдореИрдВ рдЗрди рд╕рднреА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЦреЛ рдЧрдпрд╛ рд╣реВрдВ, рдХреНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдПрдХреНрд╕рдкреНрд░реЗрд╕ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд░ (рдЗрд╕ рд░реЗрдкреЛ рд╕реЗ рдПрдХ рдХреА рдирдХрд▓ рдХрд░рдирд╛) рдХреИрд╕рд╛ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП?

function getStatusCodeFromResponse(error) {
    const statusCode = error.status || error.statusCode || error.status_code || (error.output && error.output.statusCode);
    return statusCode ? parseInt(statusCode, 10) : 500;
}

app.use(async (err, req, res, next) => {
    const status = getStatusCodeFromResponse(err);

    if (status >= 500) {
        Sentry.captureException(err)

        await Sentry.getCurrentHub().getClient().close(2000)
    }

    next(err)
})

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ рдФрд░ рдпрд╣ @rreynier рдХреЗ рдХреЛрдб рдХреА рддрд░рд╣ рдЕрддрд┐рд░рд┐рдХреНрдд рдбреЗрдЯрд╛ рдирд╣реАрдВ рдЦреЛрддрд╛ рд╣реИред

рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐

await Sentry.getCurrentHub().getClient().captureException(err)

рд╕реЗ рдХреНрд▓реАрдирд░ рд╣реИ:

Sentry.captureException(err)
await Sentry.getCurrentHub().getClient().close(2000)

close рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрдврд╝рддрд╛ рд╣реИ рдЬреИрд╕реЗ рдпрд╣ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдмрдВрдж рдХрд░ рджреЗрдЧрд╛ ...

рдкреВрд░рд╛ рдЙрджрд╛рд╣рд░рдг:

import * as Sentry from '@sentry/node'

// ...

Sentry.init({ dsn: config.SENTRY_DSN })

// ...

app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
  let status = (err.status || err.statusCode || 500) as number

  if (process.env.NODE_ENV === 'test') {
    return next(err)
  }

  if (status < 400 || status >= 500) {
    Sentry.getCurrentHub().getClient().captureException(err).then(() => next(err))
  } else {
    next(err)
  }
})

@LinusU рдореИрдВрдиреЗ рдХреЛрд╢рд┐рд╢ рдХреА рдФрд░ рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ, рдпрд╣ рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕ рдХреЗ рд╕рд╛рде рдЕрддрд┐рд░рд┐рдХреНрдд рдбреЗрдЯрд╛ рдирд╣реАрдВ рднреЗрдЬрддрд╛ рд╣реИред рдпрд╣ рдореВрд▓ рд░реВрдк рд╕реЗ рд╕рд┐рд░реНрдл рд╕реНрдЯреИрдХ рдЯреНрд░реЗрд╕ рднреЗрдЬрддрд╛ рд╣реИред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛, рдУрдПрд╕ рдпрд╛ рдХреБрдЫ рднреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЛрдИ рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВред

рдЖрд╣, рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ

рдЬрдмрдХрд┐ рд╣рдо flush рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВ, рдЙрдкрд░реЛрдХреНрдд рджреЛрдиреЛрдВ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд╕рдорд╛рдзрд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рдЖрдк рд░рд┐рдкреЛрд░реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, _рдФрд░_ рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рд╕реНрдирд┐рдкреЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджрд╛рдпрд░рд╛ рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВ:

const scope = Sentry.getCurrentHub().getScope();
await Sentry.getCurrentHub().getClient().captureException(error, scope);

рдореИрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдФрд░ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореЗрд░реЗ рд▓рд┐рдП рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд░рд┐рдкреЛрд░реНрдЯ рдХреА рдЧрдИ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдЬреЛ рдХреБрдЫ рднреА рдореИрдВ рдЙрдореНрдореАрдж рдХрд░рддрд╛ рд╣реВрдВред

рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдиреЗрдЯрд▓рд┐рдлрд╛рдИ рдлрдВрдХреНрд╢рдВрд╕ рдХреЗ рд╕рд╛рде рдпрд╣ рд╕рдм рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рд╕рд┐рджреНрдзрд╛рдВрдд рд▓реИрдореНрдмреНрдбрд╛ рдЖрджрд┐ рдХреЗ рд╕рд╛рде рд╕рдорд╛рди рд╣реИред рдореИрдВрдиреЗ рдПрдХ рдкреЛрд╕реНрдЯ рд▓рд┐рдЦрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреВрд░реА рдЬрд╛рдирдХрд╛рд░реА рд╣реИ, рдЕрдЧрд░ рдХреЛрдИ рджрд┐рд▓рдЪрд╕реНрдкреА рд▓реЗрддрд╛ рд╣реИ: https://httptoolkitред рддрдХрдиреАрдХ/рдмреНрд▓реЙрдЧ/netlify-рдлрд╝рдВрдХреНрд╢рди-рддреНрд░реБрдЯрд┐-рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ-рд╕рд╛рде-рд╕рдВрддрд░реА/

рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЕрдкрдиреЗ рд╕рднреА рд▓реИрдореНрдмреНрдбрд╛ рдореЗрдВ рдЗрд╕ рд╕рд╣рд╛рдпрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред

@pimterry рдХреНрдпрд╛ рдпрд╣ рдореВрд▓ рд░реВрдк рд╕реЗ рд╡рд╣реА рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реИ рдЬреИрд╕рд╛ @LinusU рдиреЗ рд╕реБрдЭрд╛рдпрд╛ рдерд╛? рдореИрдВрдиреЗ рдЗрд╕реЗ рдЖрдЬрдорд╛рдпрд╛ рд╣реИ рдФрд░ рдпрд╣ рдЕрддрд┐рд░рд┐рдХреНрдд рдбреЗрдЯрд╛ рднреА рдирд╣реАрдВ рднреЗрдЬрддрд╛ рд╣реИред

рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдиреЗ рдореЗрд░реЗ рд▓рд┐рдП рдЕрдм рддрдХ рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИ @ondrowan

@ondrowan рдпрд╣ рд╡рд╣реА рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╣рдерд┐рдпрд╛рдиреЗ рдФрд░ рд╡рд░реНрддрдорд╛рди рджрд╛рдпрд░реЗ рд╕рд╣рд┐рддред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдЕрдкрд╡рд╛рдж рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде, рдореБрдЭреЗ рдмрд┐рдирд╛ рд▓реЗрдмрд▓ рд╡рд╛рд▓реА рдШрдЯрдирд╛рдПрдВ рдорд┐рд▓ рд░рд╣реА рдереАрдВ, рдФрд░ рдЕрдм рдЗрд╕ рдмрджрд▓рд╛рд╡ рдХреЗ рд╕рд╛рде рдореЗрд░реЗ рдЕрдкрд╡рд╛рдж рд╕рднреА рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдЖрддреЗ рд╣реИрдВред

@vietbui @albinekb @Andriy- Kulak @LinusU @dwelch2344 @jviolas @rreynier @guillaumekh @rdsedmundo @ondrowan @pimterry @zeusdeux рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИрдВ рдХрд┐ рдЗрд╕ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЕрднреА рднреА рдХреМрди рд░реБрдЪрд┐ рд░рдЦрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдХреНрд╖рдорд╛ рдХрд░реЗрдВ рдпрджрд┐ рдореБрдЭреЗ рдЖрдкрдХреЛ рдХреЙрд▓ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

4.6.0 рд╕реЗ рд╢реБрд░реВ рд╣реЛрдХрд░, рдЕрдм рдХреЛрдИ client/hub рдиреГрддреНрдп рдирд╣реАрдВ рд╣реИред рдЖрдк рдмрд╕ рд╣рдорд╛рд░реА рдХрд┐рд╕реА рднреА captureX рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рд╕рд░реНрд╡рд░ рдкрд░ рд╕рдм рдХреБрдЫ рднреЗрдЬреЗ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП Sentry.flush() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕рднреА рджрд╛рдпрд░реЗ/рдЕрддрд┐рд░рд┐рдХреНрдд рдбреЗрдЯрд╛ рдХреЛ рдмрд┐рдирд╛ рдХрд┐рд╕реА рджреЗрд╡ рд╕рд╣рднрд╛рдЧрд┐рддрд╛ рдХреЗ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╕рдлрд▓/рд╕рдордп рд╕рдорд╛рдкреНрдд рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд╕рд╛рде рдпрд╣рд╛рдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

image

рдЖрд╢рд╛ рд╣реИ рдпреЗ рдорджрдж рдХрд░реЗрдЧрд╛! :)

рдЕрдЪреНрдЫрд╛!

рдХреНрдпрд╛ рдЕрднреА рднреА рд▓реИрдореНрдмреНрдбрд╛ рдФрд░ рдЕрдиреНрдп рд╕рд░реНрд╡рд░ рд░рд╣рд┐рдд рд╕рдорд╛рдзрд╛рдиреЛрдВ рд╕реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдиреНрдпреВрдирддрдо рдкреИрдХреЗрдЬ рдмрдирд╛рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рд╣реИ? рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрднреА рднреА рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдЬреЛрдбрд╝ рд╣реЛрдЧрд╛ тЭдя╕П

@LinusU рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рд╣рд╛рдБ, рд▓реЗрдХрд┐рди рд╣рдо рдЕрднреА рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ рдХреЗ рдПрд╕рдбреАрдХреЗ рдХреЗ рд╕рд╛рде рдмрд╣ рдЧрдП рд╣реИрдВ

рд╕рднреА рд╕рдВрднрд╛рд╡рд┐рдд рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдпрд╣рд╛рдВ рдЖрдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЯреАрдПрд▓; рдбреЙ

рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ: await Sentry.flush() рд╕рднреА рд▓рдВрдмрд┐рдд рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ 4.6.x рдореЗрдВ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдЗрд╕реЗ рдмрдВрдж рдХрд░рддреЗ рд╣реБрдП, рдХреГрдкрдпрд╛ рдмреЗрдЭрд┐рдЭрдХ рдПрдХ рдирдпрд╛ рдЕрдВрдХ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣реЗрдВ, рдЕрдЧрд░ рдХреБрдЫ рднреА рдЧрд╛рдпрдм рд╣реИ (рд▓реЗрдХрд┐рди рдпрд╣ рдзрд╛рдЧрд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рд▓рдВрдмрд╛ рд╣реИ)ред

рдЪреАрдпрд░реНрд╕

@kamilogorek рдЕрд░реЗ! рдПрдХ рддреНрд╡рд░рд┐рдд fyi, рдореИрдВ рдкреБрд░рд╛рдиреЗ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдХреЗ рд╕реНрдерд╛рди рдкрд░ рдЕрдкрдиреЗ рдРрдк рдореЗрдВ Sentry.flush рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдХрд┐рд╕реА рднреА рддреНрд░реБрдЯрд┐ рдХреА рд╕реВрдЪрдирд╛ рдирд╣реАрдВ рджреА рдЬрд╛ рд░рд╣реА рд╣реИред рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЕрджреНрдпрддрди flush рдкрджреНрдзрддрд┐ рд╕реЗ рдкреБрд░рд╛рдиреЗ рд╕рдорд╛рдзрд╛рди рдкрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯ рд░рд╣рд╛ рд╣реВрдВред

@zeusdeux рдХреНрдпрд╛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрдк рдХреБрдЫ рдбреАрдмрдЧ рдЬрд╛рдирдХрд╛рд░реА/рд░реЗрдкреНрд░реЛ рдХреЗрд╕ рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?
рдЖрдк captureException рд╡рд┐рдзрд┐ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬреЛ рдИрд╡реЗрдВрдЯ рдХреЛ рдмрдлрд░ рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЖрдкрдХреЛ flush await рдЪрд╛рд╣рд┐рдПред рдХреНрдпрд╛ рдЖрдкрдиреЗ рдЗрд╕реЗ "рдирд┐рдпрдорд┐рдд рддрд░реАрдХреЗ рд╕реЗ" рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рд╣реИ?

@kamilogorek рдореЗрд░реА рдЗрдЪреНрдЫрд╛ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдбреАрдмрдЧ рдЬрд╛рдирдХрд╛рд░реА рд╣реЛ рд▓реЗрдХрд┐рди рд▓реЙрдЧ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИред рдореИрдВрдиреЗ рд╣рдореЗрд╢рд╛ await рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб captureException рдкрд░ рдХрд┐рдпрд╛ ред рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ, рдХреНрдпрд╛ рдЖрдкрдХрд╛ рдорддрд▓рдм captureException рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд┐рдП рдмрд┐рдирд╛ рд╣реИ?

@zeusdeux рдмрд┐рд▓реНрдХреБрд▓, рдмрд┐рдирд╛ рдХрд┐рд╕реА рдУрд╡рд░рд░рд╛рдЗрдб рдХреЗ рд╣рдорд╛рд░реЗ рдореВрд▓ Sentry.captureException(error) рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВред

рддреЛ рдЖрдкрдХрд╛ рд╕рд╣рд╛рдпрдХ рд╣реЛрдЧрд╛:

import * as Sentry from '@sentry/node'

export function init({ host, method, lambda, deployment }) {
  const environment = host === process.env.PRODUCTION_URL ? 'production' : host

  Sentry.init({
    dsn: process.env.SENTRY_DSN,
    environment,
    beforeSend(event, hint) {
      if (hint && hint.originalException) {
        // eslint-disable-next-line
        console.log('Error:', hint.originalException);
      }
      return event;
    }
  })

  Sentry.configureScope(scope => {
    scope.setTag('deployment', deployment)
    scope.setTag('lambda', lambda)
    scope.setTag('method', method)
  })
}

рдФрд░ рдХреЛрдб рдореЗрдВ рдЖрдк рдЗрд╕реЗ рдХрд╣рддреЗ рд╣реИрдВ:

import * as Sentry from '@sentry/node'

try {
  // ...
} catch (err) {
  Sentry.captureException(err);
  await Sentry.flush(2000);
  return respondWithError('Something went wrong', 500);
}

@kamilogorek рдореИрдВ рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛ рджреВрдВрдЧрд╛ рдФрд░ рд╡рд╛рдкрд╕ рд░рд┐рдкреЛрд░реНрдЯ рдХрд░реВрдВрдЧрд╛ред рд╕рд╛рде рд╣реА, beforeSend ^_^ . рдкрд░ рдЯрд┐рдк рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж

await Sentry.flush(2000);

рдореЗрд░реЗ рд▓рд┐рдП рднреА ~ рдирд╣реАрдВ ~ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред

@tanduong рдХреНрдпрд╛ рдЖрдк рд░реЗрдкреНрд░реЛ рдХреЗрд╕ рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ? рдХреЗрд╡рд▓ рдпрд╣ рдХрд╣рдирд╛ рдХрд┐ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдмрд╣реБрдд рдорджрджрдЧрд╛рд░ рдирд╣реАрдВ рд╣реИ

@kamilogorek рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдореБрдЭреЗ рдЕрднреА рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐

await Sentry.getCurrentHub().getClient().close(2000)

рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдореЗрд░рд╛ рд▓реИрдореНрдмреНрдбрд╛ рдлрд╝рдВрдХреНрд╢рди рд╡реАрдкреАрд╕реА рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИред

рдореИрдВ рдкреБрд╖реНрдЯрд┐ рдХрд░рддрд╛ рд╣реВрдБ рдХрд┐

await Sentry.flush(2000);

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред

BTW, рддреЛ рдЖрдк VPC рдореЗрдВ рд▓реИрдореНрдмреНрдбрд╛ рд╕реЗ рдХреИрд╕реЗ рдирд┐рдкрдЯреЗрдВрдЧреЗ? NAT рдЧреЗрдЯрд╡реЗ рд╕реЗ рдЕрдЯреИрдЪ рдХрд░реЗрдВ? рдореБрдЭреЗ рд╕рд┐рд░реНрдл рд╕рдВрддрд░реА рдЪрд╛рд╣рд┐рдП рд▓реЗрдХрд┐рди рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЗрдВрдЯрд░рдиреЗрдЯ рдирд╣реАрдВред

@tanduong рд╕рдВрддрд░реА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдкрдХрд╛ рд▓реИрдореНрдмреНрдбрд╛ рдЖрдкрдХреЗ VPC рдХреЗ рднреАрддрд░ рдЪрд▓ рд░рд╣рд╛ рд╣реИ, рддреЛ рд╣рд╛рдБ рдЖрдкрдХреЗ рдкрд╛рд╕ NAT рдЧреЗрдЯрд╡реЗ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдиреНрдпрдерд╛ рдЖрдкрдХреЛ рд╣реЛрд╕реНрдЯреЗрдб рд╕рдВрддрд░реА рд╡рд┐рдХрд▓реНрдк рддрд▓рд╛рд╢рдирд╛ рд╣реЛрдЧрд╛ред

flush(2000) рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рдХрд░ рд░рд╣рд╛ рд╣реИ? рдореЗрд░реЗ рдкрд╛рд╕ рдпрд╣ рдХреЛрдб рдЕрдзрд┐рдХрддрд░ рдареАрдХ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рдерд╛ рд▓реЗрдХрд┐рди рдЕрдм рдореЗрд░реЗ рдкрд╛рд╕ рдХреБрдЫ captureMessage рдХреЙрд▓ рдПрдХ рд╕рд╛рде рд╣реЛ рд░рд╣реА рд╣реИрдВ, рдпрд╣ рд╣рд░ рдмрд╛рд░ рд╕рдордп рд╕рдорд╛рдкреНрдд рд╣реЛ рд░рд╣рд╛ рд╣реИ!

рд╡рд╛рдпрд░ рдкрд░ рд╕рдВрджреЗрд╢реЛрдВ рдХреА рдЖрдВрддрд░рд┐рдХ рдХрддрд╛рд░ рдХреЛ рдлреНрд▓рд╢ рдХрд░рдирд╛

рдареАрдХ рд╣реИ, рдпрд╣ рдХреБрд▓ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореЗрд░рд╛ рдореБрджреНрджрд╛ рддреЛ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд╛рджрд╛ рдХрднреА рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ рдЬрдм рдлреНрд▓рд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдХреБрдЫ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ? рдЬрдм рднреА рдореИрдВ рдЕрдкрдиреЗ рд▓рдкреЗрдЯреЗ рд╣реБрдП captureException fn рдХреЛ рд╕рдорд╡рд░реНрддреА рд░реВрдк рд╕реЗ рдЪрд▓рд╛рддрд╛ рд╣реВрдВ рддреЛ рдпрд╣ рдореЗрд░реЗ рд╣реИрдВрдбрд▓рд░ рд╕реЗ рдмрд╛рд╣рд░ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

export const captureMessage = async (
  message: string,
  extras?: any,
): Promise<boolean> =>
  new Promise((resolve) => {
    Sentry.withScope(async (scope) => {
      if (typeof extras !== 'undefined') {
        scope.setExtras(extras)
      }
      Sentry.captureMessage(message)
      await Sentry.flush(2000)
      resolve(true)
    })
  })

await Sentry.flush() рдкрд╣рд▓реЗ рдХреИрдкреНрдЪрд░ рдореИрд╕реЗрдЬ рдХреЙрд▓ рдХреЗ рдмрд╛рдж рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдорд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

рдореЗрд░реЗ рдкрд╛рд╕ рд╡рд╣реА рд╣реИ рдЬреЛ рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ @enapupe рдЬреИрд╕рд╛ рд╣реА рдореБрджреНрджрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ await client.flush(2000); рдкрд░ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдХреЗрд╡рд▓ рдкрд╣рд▓рд╛ рд╡рд╛рджрд╛ рд╣рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдПрдбрдмреНрд▓реНрдпреВрдПрд╕ рд▓реИрдореНрдмреНрдбрд╛ рд╕рдВрджрд░реНрднреЛрдВ рдореЗрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХрдИ рд╕рдорд╡рд░реНрддреА рдХреЙрд▓реЛрдВ рдХреЗ рдмреАрдЪ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдореИрдВ рдЗрд╕ рддрд░рд╣ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдБ:

 let client = Sentry.getCurrentHub().getClient();
  if (client) {
    // flush the sentry client if it has any events to send
    log('begin flushing sentry client');
    try {
      await client.flush(2000);
    } catch (err) {
      console.error('sentry client flush error:', err);
    }
    log('end flushing sentry client');
  }

рд▓реЗрдХрд┐рди рдЬрдм рдореИрдВ рдЕрдкрдиреЗ рд▓реИрдореНрдмреНрдбрд╛ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рддреЗрдЬреА рд╕реЗ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░ рдореЗрдВ рджреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдореБрдЭреЗ рдорд┐рд▓рддрд╛ рд╣реИ:

  app begin flushing sentry client +2ms
  app begin flushing sentry client +0ms
  app end flushing sentry client +2ms

рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рджреВрд╕рд░рд╛ рд╡рд╛рджрд╛ рдХрднреА рд╣рд▓ рдирд╣реАрдВ рд╣реБрдЖред

@esetnik рдореИрдВрдиреЗ рдЙрд╕ рдкрд░ рдПрдХ рд╕рдорд╕реНрдпрд╛ рджрд░реНрдЬ рдХреА рд╣реИ: https://github.com/getsentry/sentry-javascript/issues/2131
рдореЗрд░рд╛ рдХрд░рдВрдЯ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдПрдХ рд░реИрдкрд░ рдлреНрд▓рд╢ fn рд╣реИ рдЬреЛ рд╣рдореЗрд╢рд╛ рд╣рд▓ рд╣реЛрддрд╛ рд╣реИ (рдЯрд╛рдЗрдордЖрдЙрдЯ рдХреЗ рдЖрдзрд╛рд░ рдкрд░):

const resolveAfter = (ms: number) =>
  new Promise((resolve) => setTimeout(resolve, ms))

const flush = (timeout: number) =>
  Promise.race([resolveAfter(timeout), Sentry.flush(timeout)])

@enapupe рдореИрдВрдиреЗ #2131 рдореЗрдВ рдЖрдкрдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдиреЛрдЯ рдЬреЛрдбрд╝рд╛ред рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛтАЛтАЛрд╣реИ рдХрд┐ рдпрд╣ рд╕рдорд╡рд░реНрддреА рдлреНрд▓рд╢ рдкрд░ рдкреНрд░рджрд░реНрд╢рди рд░рд┐рдЧреНрд░реЗрд╢рди рдХрд╛ рдХрд╛рд░рдг рдмрди рдЬрд╛рдПрдЧрд╛ред

рдЕрдЧрд░ рдХрд┐рд╕реА рдХреЛ рдХреЛрдИ рдкрд░реЗрд╢рд╛рдиреА рд╣реЛ рд░рд╣реА рд╣реИред
рдпрд╣ рдЦреВрдмрд╕реВрд░рддреА рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ

@рд╕рд░рд╕рдЖрд░реНрдпрд╛ @HazAT
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ... рдЕрдкрдирд╛ рд╕рдорд╛рдзрд╛рди рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж! :)
configScope рд╡рд┐рдзрд┐ рдХрд╛ рдПрдХ рдХреЙрд▓рдмреИрдХ рд╣реИ рдЬреЛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреИрдкреНрдЪрд░ рдЕрдкрд╡рд╛рдж рд╕реЗ рдкрд╣рд▓реЗ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рд▓реЗрдХрд┐рди рдпрд╣ рдЙрд╕реА "рдереНрд░реЗрдб" рдореЗрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред
рдХреНрдпрд╛ рдпрд╣ рджреМрдбрд╝ рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХрд╛ рдХрд╛рд░рдг рдирд╣реАрдВ рдмрди рд╕рдХрд╛?

@cibergarri рдореБрдЭреЗ рдРрд╕рд╛ рдирд╣реАрдВ рд▓рдЧрддрд╛, рдореЗрд░реЗ рд▓рд┐рдП рддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рджрд┐рдЦрддрд╛ рд╣реИ, рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рд╡рд╣рд╛рдВ рдПрдХ рдПрд╕рд┐рдВрдХ рд╡рд┐рдзрд┐ рд╣реИ, рддреЛ рджреМрдбрд╝ рдХреА рд╕реНрдерд┐рддрд┐ рд╣реЛрдЧреАред
рд╡рд┐рдЪрд╛рд░ рд╕рд░рдгреА рдХреЗ рдорд╛рдирдЪрд┐рддреНрд░ рдЬреИрд╕рд╛ рд╣реИ рдХрд┐ рд╡рд╣реА рдмрд╛рдд рдпрд╣рд╛рдВ рд╣реЛ рд░рд╣реА рд╣реИред рдпрджрд┐ рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЕрдкрдирд╛ рд╕рд┐рд░ рд▓рдкреЗрдЯрдиреЗ рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рд╣реИред рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рд╡рд╣ рдорджрдж рдХрд░реЗрдВрдЧреЗред

рд╣рд╛рдБ, рдРрд╕рд╛ рдХрд░рдирд╛ рдмрд┐рд▓рдХреБрд▓ рдареАрдХ рд╣реИ

рдЕрдкрдбреЗрдЯ: рд╕рдВрддрд░реА рдЕрдм рдиреЛрдб/рд▓реИрдореНрдмреНрдбрд╛ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рд▓рд┐рдП рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рддреНрд░реБрдЯрд┐ рдХреИрдкреНрдЪрд░ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ: https://docs.sentry.io/platforms/node/guides/aws-lambda/

рдореИрдВ рдЗрд╕ рддрд░рд╣ @ рд╕рдВрддрд░реА/рд╕рд░реНрд╡рд░ рд░рд╣рд┐рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ:

const Sentry = require("@sentry/serverless");
Sentry.AWSLambda.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 1.0,
  environment: appEnv
});

exports.main = Sentry.AWSLambda.wrapHandler(async (event, context) => {
     try{
           //my code
     }catch(error){
          Sentry.captureException(error);
          await Sentry.flush(3000);
     }

});

рдпрд╣ рд▓реИрдореНрдмреНрдбрд╛ рдкрд░ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
рдореЗрд░реЗ рдкрд░реАрдХреНрд╖рдг рдПрдирд╡реА рдореЗрдВ рдпрд╣ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рдерд╛ рд▓реЗрдХрд┐рди рдкреНрд░реЛрдб рдореЗрдВ рдЬрд╣рд╛рдВ рдПрдХ рд╕рдорд╡рд░реНрддреА рдирд┐рд╖реНрдкрд╛рджрди рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдХрдВрдЯреЗрдирд░реЛрдВ рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣ рдХреБрд▓ рд░рд╛рд╢рд┐ рдХрд╛ рд▓рдЧрднрдЧ 10% рд▓реЙрдЧрд┐рдВрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИред

рдХреЛрдИ рд╕рд▓рд╛рд╣?

@ рдЕрд░рдорд╛рдВрдбреЛ25723

рдХреГрдкрдпрд╛ рдмрддрд╛рдПрдВ рдХрд┐ рдЖрдкрдиреЗ рдпрд╣ рдХреИрд╕реЗ рдорд╛рдк рд▓рд┐рдпрд╛ рдХрд┐ рдпрд╣ рдЕрдкрд╡рд╛рдж рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЦреЛ рджреЗрддрд╛ рд╣реИ? рдХреНрдпрд╛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдХреЛрдб рдирдореВрдирд╛ рд╣реИ рдХрд┐ рдЗрд╕ рддрд░рд╣ рдХреЗ рдЦреЛрдП рд╣реБрдП рдЕрдкрд╡рд╛рдж рдХреЛ рдХреИрд╕реЗ рдлреЗрдВрдХрд╛ рдЧрдпрд╛? рдЕрдзрд┐рдХ рд╕рдВрджрд░реНрдн рдЪрд╛рд╣рд┐рдПред

const Sentry = require("@sentry/serverless"); // "version": "5.27.3"
Sentry.AWSLambda.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 1.0,
  environment: appEnv
});
exports.main = Sentry.AWSLambda.wrapHandler(async (event, context) => {
     try{
           throw new Error('Test Error');
     }catch(error){
          Sentry.captureException(error);
          await Sentry.flush(3000);
     }
});

рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ?
рдпрджрд┐ рдЖрдордВрддреНрд░рдгреЛрдВ рдХреЗ рдмреАрдЪ рдЫреЛрдЯреЗ рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд╕рд╛рде рдХрдИ рдмрд╛рд░ рдлрд╝рдВрдХреНрд╢рди рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдИрд╡реЗрдВрдЯ рдХреЗрд╡рд▓ рдПрдХ рдмрд╛рд░ рд▓реЙрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдпрджрд┐ рдЗрдирд╡реЛрдХреЗрд╢рди рдХреЗ рдмреАрдЪ рдХрд╛ рд╕рдордп рдЕрдВрддрд░рд╛рд▓ рдмрдбрд╝рд╛ рд╣реИ рддреЛ рд╕рднреА рдЗрд╡реЗрдВрдЯ рд▓реЙрдЧ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рддрдм рд╣реЛрддреА рд╣реИ рдЬрдм рдЖрдордВрддреНрд░рдг рдПрдХ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдХрдВрдЯреЗрдирд░ рдкрд░ рд╣реЛрддрд╛ рд╣реИред

рдореИрдВрдиреЗ рднреА рдХреЛрд╢рд┐рд╢ рдХреА рд╣реИ
await Sentry.captureException(error);
рддрдерд╛:
await Sentry.flush();
рдФрд░ рдирд┐рд╕реНрддрдмреНрдзрддрд╛ рдХреЗ рдмрд┐рдирд╛
рд╡рд╣реА рдкрд░рд┐рдгрд╛рдо

@ рдорд╛рд░реНрд╢рд▓-рд▓реА рдЖрдк рдХреНрдпрд╛ рд╕рд▓рд╛рд╣ рджреЗрддреЗ рд╣реИрдВ? рдХреНрдпрд╛ рдореБрдЭреЗ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдкреИрджрд╛ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП, рдореИрдВ рдпрд╣рд╛рдБ рдлрдВрд╕ рдЧрдпрд╛ рд╣реВрдБред

@ armando25723 рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рд░реНрд╡рд░ рдЗрди рдШрдЯрдирд╛рдУрдВ рдХреЛ рднреЗрдЬрддреЗ рд╕рдордп 429 (рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЕрдкрд╡рд╛рдж) рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗ рд░рд╣рд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ рдЕрдзрд┐рдХ рдХреЛрдЯрд╛/рджрд░ рд╕реАрдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдлреЗрдВрдХ рджреЗрддреЗ рд╣реИрдВред рдХреНрдпрд╛ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рддреНрд░реБрдЯрд┐рдпрд╛рдБ рднреЗрдЬ рд░рд╣реЗ рд╣реИрдВ рдпрд╛ рдХреЛрдЯрд╛ рд╕реЗ рдЕрдзрд┐рдХ? рд╣рдо рдЖрдЧреЗ рдбрд┐рдмрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрджрд┐ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рддреНрд░реБрдЯрд┐ рдШрдЯрдирд╛рдПрдВ рд╣реИрдВ рдФрд░ рдЖрдк рдлреНрд░реА рдЯрд┐рдпрд░ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реА 5k рд╕реАрдорд╛ рдХреЗ рдЕрдВрддрд░реНрдЧрдд рд╣реИрдВред

@ajjindal рдЕрдиреНрдп рд╕рднреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдПрдВ рд╕рдВрддрд░реА рдХреЗ рд╕рд╛рде рдареАрдХ рдХрд╛рдо рдХрд░ рд░рд╣реА рд╣реИрдВред рд╕рдВрдЧрдарди рд╕реНрд▓рдЧ "рдПрд▓реЗрдЧреНрд░рд╛" рд╣реИ, рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХрд╛ рдирд╛рдо рдореЗрд▓-рдбрд┐рд╕реНрдкреИрдЪ-рд╕рд░реНрд╡рд░ рд░рд╣рд┐рдд рд╣реИ #mail-micros рдХреЗ рдЕрдВрддрд░реНрдЧрддред рд╣рдо рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рд╕рдВрддрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдкрд╣рд▓реА рдмрд╛рд░ рд╕рд░реНрд╡рд░ рд░рд╣рд┐рддред рдпрд╣ рдлреНрд░реА рдЯрд┐рдпрд░ рдирд╣реАрдВ рд╣реИ, рдореИрдВ рдЖрдкрдХреЛ рдпрд╣ рдирд╣реАрдВ рдмрддрд╛ рд╕рдХрддрд╛ рдХрд┐ рд╣рдо рдХрд┐рд╕ рдкреНрд▓рд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рд▓реЗрдХрд┐рди рдпрд╣ рдкреЗрдб рд╣реИред
рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЖрдк рдореБрдЭреЗ рдФрд░ рдбреАрдмрдЧ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХреЗрдВред
рдЬрд╡рд╛рдм рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж : )

рдкреАрдбреА: рдЯреАрдо рдкреНрд▓рд╛рди рд╣реИ

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

dwelle picture dwelle  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

franciscovelez picture franciscovelez  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

mogelbrod picture mogelbrod  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

mattkrick picture mattkrick  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

adepue picture adepue  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ