Add more try/catch blocks in processQueueItem for more granular errors reported
This commit is contained in:
Родитель
5602b6e741
Коммит
382ee2b851
|
@ -10,6 +10,8 @@ const Sentry = require("../lib/sentry");
|
||||||
const Metrics = require("../lib/metrics");
|
const Metrics = require("../lib/metrics");
|
||||||
const { wait, epochNow } = require("../lib/utils.js");
|
const { wait, epochNow } = require("../lib/utils.js");
|
||||||
|
|
||||||
|
const Raven = Sentry();
|
||||||
|
|
||||||
exports.handler = async function(event = {}, context = {}) {
|
exports.handler = async function(event = {}, context = {}) {
|
||||||
const { Records } = event;
|
const { Records } = event;
|
||||||
const log = require("../lib/logging")({
|
const log = require("../lib/logging")({
|
||||||
|
@ -90,8 +92,6 @@ exports.handleOne = async function(event, context) {
|
||||||
EMAIL_EXPIRES,
|
EMAIL_EXPIRES,
|
||||||
} = process.env;
|
} = process.env;
|
||||||
|
|
||||||
const Raven = Sentry();
|
|
||||||
|
|
||||||
log.verbose("env", {
|
log.verbose("env", {
|
||||||
HITRATE_TABLE,
|
HITRATE_TABLE,
|
||||||
Bucket,
|
Bucket,
|
||||||
|
@ -132,6 +132,20 @@ exports.handleOne = async function(event, context) {
|
||||||
|
|
||||||
log.info("processing", { id });
|
log.info("processing", { id });
|
||||||
|
|
||||||
|
const handleError = async (err, logType, extra = {}, isDone = true) => {
|
||||||
|
Raven.captureException(err);
|
||||||
|
metricsPing.is_error = true;
|
||||||
|
log.error(logType, Object.assign({ err }, extra));
|
||||||
|
return isDone ? done() : Promise.resolve();
|
||||||
|
};
|
||||||
|
|
||||||
|
const done = async () => {
|
||||||
|
const metricsResult = await Metrics.workerWorks(metricsPing);
|
||||||
|
log.verbose("metricsResult", { metricsResult });
|
||||||
|
return id;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Step #1: Handle rate limiting and pause if necessary
|
||||||
try {
|
try {
|
||||||
// Pause if we're at the rate limit for current expiration window
|
// Pause if we're at the rate limit for current expiration window
|
||||||
let rateLimited = false;
|
let rateLimited = false;
|
||||||
|
@ -168,7 +182,13 @@ exports.handleOne = async function(event, context) {
|
||||||
.promise();
|
.promise();
|
||||||
|
|
||||||
log.verbose("hitRatePutResult", { hitRatePutResult });
|
log.verbose("hitRatePutResult", { hitRatePutResult });
|
||||||
|
} catch (err) {
|
||||||
|
return handleError(err, "hitRateError");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step #2: Make a request to the upstream service
|
||||||
|
let upstreamServiceResponse, IsMatch;
|
||||||
|
try {
|
||||||
const imageUrl = S3.getSignedUrl("getObject", {
|
const imageUrl = S3.getSignedUrl("getObject", {
|
||||||
Bucket,
|
Bucket,
|
||||||
Key: image,
|
Key: image,
|
||||||
|
@ -180,7 +200,7 @@ exports.handleOne = async function(event, context) {
|
||||||
metricsPing.timing_sent = Date.now() - Date.parse(datestamp);
|
metricsPing.timing_sent = Date.now() - Date.parse(datestamp);
|
||||||
|
|
||||||
const timingReceivedStart = Date.now();
|
const timingReceivedStart = Date.now();
|
||||||
const upstreamServiceResponse = await request.post({
|
upstreamServiceResponse = await request.post({
|
||||||
url: `${upstreamServiceUrl}?enhance`,
|
url: `${upstreamServiceUrl}?enhance`,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
@ -195,20 +215,29 @@ exports.handleOne = async function(event, context) {
|
||||||
metricsPing.timing_received = Date.now() - timingReceivedStart;
|
metricsPing.timing_received = Date.now() - timingReceivedStart;
|
||||||
metricsPing.photodna_tracking_id = upstreamServiceResponse.TrackingId;
|
metricsPing.photodna_tracking_id = upstreamServiceResponse.TrackingId;
|
||||||
|
|
||||||
log.verbose("upstreamServiceResponse", { upstreamServiceResponse });
|
({ IsMatch } = upstreamServiceResponse);
|
||||||
|
|
||||||
const { IsMatch } = upstreamServiceResponse;
|
|
||||||
metricsPing.is_match = IsMatch;
|
metricsPing.is_match = IsMatch;
|
||||||
|
|
||||||
|
log.verbose("upstreamServiceResponse", { upstreamServiceResponse });
|
||||||
|
} catch (err) {
|
||||||
|
return handleError(err, "upstreamServiceError");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step #3: Handle the response from the upstream service
|
||||||
if (!IsMatch) {
|
if (!IsMatch) {
|
||||||
// On negative match, clean up the image and request details.
|
try {
|
||||||
|
// Step #3a: On negative match, clean up the image and request details.
|
||||||
const deleteResult = await Promise.all([
|
const deleteResult = await Promise.all([
|
||||||
S3.deleteObject({ Bucket, Key: `${image}` }).promise(),
|
S3.deleteObject({ Bucket, Key: `${image}` }).promise(),
|
||||||
S3.deleteObject({ Bucket, Key: `${image}-request.json` }).promise(),
|
S3.deleteObject({ Bucket, Key: `${image}-request.json` }).promise(),
|
||||||
]);
|
]);
|
||||||
log.verbose("deleteResult", { deleteResult });
|
log.verbose("deleteResult", { deleteResult });
|
||||||
|
} catch (err) {
|
||||||
|
return handleError(err, "deleteError");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// On positive match, store the details of the match response.
|
try {
|
||||||
|
// Step #3b: On positive match, store the details of the match response.
|
||||||
const putResult = await S3.putObject({
|
const putResult = await S3.putObject({
|
||||||
Bucket,
|
Bucket,
|
||||||
Key: `${image}-response.json`,
|
Key: `${image}-response.json`,
|
||||||
|
@ -226,8 +255,14 @@ exports.handleOne = async function(event, context) {
|
||||||
}).promise();
|
}).promise();
|
||||||
|
|
||||||
log.verbose("putResult", { putResult });
|
log.verbose("putResult", { putResult });
|
||||||
|
} catch (err) {
|
||||||
|
return handleError(err, "putError");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Send an email alert on positive match, if addresses are available.
|
// Step #4: Send an email alert on positive match.
|
||||||
|
if (IsMatch) {
|
||||||
|
try {
|
||||||
const ToAddresses = [];
|
const ToAddresses = [];
|
||||||
if (positive_email) {
|
if (positive_email) {
|
||||||
ToAddresses.push(positive_email);
|
ToAddresses.push(positive_email);
|
||||||
|
@ -291,15 +326,22 @@ exports.handleOne = async function(event, context) {
|
||||||
log.verbose("emailResult", { emailResult });
|
log.verbose("emailResult", { emailResult });
|
||||||
log.info("sentEmail", { messageId: emailResult.MessageId });
|
log.info("sentEmail", { messageId: emailResult.MessageId });
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// Do not bail out on an error from email, we can still send a callback
|
||||||
|
await handleError(err, "emailError", {}, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step #5: Send a callback request to the client service
|
||||||
|
const callbackUrl = IsMatch ? positive_uri : negative_uri;
|
||||||
|
try {
|
||||||
const timingSubmittedStart = Date.now();
|
const timingSubmittedStart = Date.now();
|
||||||
const upstreamIsError =
|
const upstreamIsError =
|
||||||
!upstreamServiceResponse ||
|
!upstreamServiceResponse ||
|
||||||
!upstreamServiceResponse.Status ||
|
!upstreamServiceResponse.Status ||
|
||||||
upstreamServiceResponse.Status.Code !== 3000;
|
upstreamServiceResponse.Status.Code !== 3000;
|
||||||
const callbackResult = await request.post({
|
const callbackResult = await request.post({
|
||||||
url: IsMatch ? positive_uri : negative_uri,
|
url: callbackUrl,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
|
@ -315,13 +357,8 @@ exports.handleOne = async function(event, context) {
|
||||||
metricsPing.timing_submitted = Date.now() - timingSubmittedStart;
|
metricsPing.timing_submitted = Date.now() - timingSubmittedStart;
|
||||||
log.verbose("callbackResult", { callbackResult });
|
log.verbose("callbackResult", { callbackResult });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Raven.captureException(err);
|
return handleError(err, "callbackError", { callbackUrl });
|
||||||
metricsPing.is_error = true;
|
|
||||||
log.error("callbackError", { err });
|
|
||||||
throw err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const metricsResult = await Metrics.workerWorks(metricsPing);
|
return done();
|
||||||
log.verbose("metricsResult", { metricsResult });
|
|
||||||
return id;
|
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче