@seasketch/geoprocessing
Version:
Geoprocessing and reporting framework for SeaSketch 2.0
103 lines • 3.58 kB
JavaScript
import { ValidationError, } from "../types/index.js";
const commonHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true,
"Access-Control-Allow-Headers": "*",
};
/**
* Lambda handler for a preprocessing function
* @template G the geometry type of the feature for the geoprocessing function, automatically set from func feature type
*/
export class PreprocessingHandler {
func;
options;
// Store last request id to avoid retries on a failure of the lambda
// aws runs several retries and there appears to be no setting to avoid this
lastRequestId;
constructor(func, options) {
this.func = func;
this.options = Object.assign({ memory: 1024 }, options);
}
async lambdaHandler(event, context) {
// TODO: Rate limiting (probably in api gateway?)
let request;
try {
request = this.parseRequest(event);
}
catch (error) {
return {
statusCode: 500,
headers: commonHeaders,
body: JSON.stringify({
error: error instanceof Error ? error.message : "Internal server error",
status: "error",
}),
};
}
// Bail out if replaying previous task
if (context.awsRequestId && context.awsRequestId === this.lastRequestId) {
// don't replay
if (process.env.NODE_ENV !== "test") {
console.log("cancelling since event is being replayed");
}
return {
statusCode: 200,
body: "",
};
}
else {
this.lastRequestId = context.awsRequestId;
}
try {
if (process.env.NODE_ENV !== "test")
console.log("request", JSON.stringify(request));
const feature = await this.func(request.feature, request.extraParams);
return {
statusCode: 200,
headers: commonHeaders,
body: JSON.stringify({
data: feature,
status: "ok",
}),
};
}
catch (error) {
if (error instanceof ValidationError) {
return {
statusCode: 200,
headers: commonHeaders,
body: JSON.stringify({
error: error.message,
status: "validationError",
}),
};
}
else {
return {
statusCode: 500,
headers: commonHeaders,
body: JSON.stringify({
error: error instanceof Error ? error.message : "Internal server error",
status: "error",
}),
};
}
}
}
parseRequest(event) {
if (!event.body) {
throw new Error("Invalid request. No request body");
}
const json = JSON.parse(event.body);
if (!json.feature || !json.feature.type) {
throw new Error("Invalid request. body.feature must be specified as valid GeoJSON");
}
return {
feature: json.feature,
// TODO: support more response types in seasketch/next
extraParams: json.extraParams || {},
responseFormat: "application/json",
};
}
}
//# sourceMappingURL=PreprocessingHandler.js.map