abap-adt-api
Version:
Interface to Abap Developer Tools webservice
185 lines (184 loc) • 7.42 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isErrorMessageType = exports.validateParseResult = exports.fromError = exports.fromResponse = exports.isLoginError = exports.AdtErrorException = exports.SAPRC = void 0;
exports.isAdtError = isAdtError;
exports.isCsrfError = isCsrfError;
exports.isHttpError = isHttpError;
exports.isAdtException = isAdtException;
exports.fromException = fromException;
exports.adtException = adtException;
exports.ValidateObjectUrl = ValidateObjectUrl;
exports.ValidateStateful = ValidateStateful;
const AdtHTTP_1 = require("./AdtHTTP");
const utilities_1 = require("./utilities");
const These_1 = require("fp-ts/lib/These");
const io_ts_reporters_1 = __importDefault(require("io-ts-reporters"));
const ADTEXTYPEID = Symbol.for("ADT EXCEPTION");
const CSRFEXTYPEID = Symbol.for("BAD CSRF");
const HTTPEXTYPEID = Symbol.for("HTTP EXCEPTION");
var SAPRC;
(function (SAPRC) {
SAPRC["Success"] = "S";
SAPRC["Info"] = "I";
SAPRC["Warning"] = "W";
SAPRC["Error"] = "E";
SAPRC["CriticalError"] = "A";
SAPRC["Exception"] = "X";
})(SAPRC || (exports.SAPRC = SAPRC = {}));
const isResponse = (r) => (0, utilities_1.isObject)(r) && !!(r === null || r === void 0 ? void 0 : r.status) && (0, utilities_1.isString)(r === null || r === void 0 ? void 0 : r.statusText);
class AdtErrorException extends Error {
get typeID() {
return ADTEXTYPEID;
}
static create(errOrResponse, properties, type, message, parent, namespace, localizedMessage, response) {
if (!(0, utilities_1.isNumber)(errOrResponse)) {
return this.create(errOrResponse.status, properties, "", errOrResponse.statusText || "Unknown error in adt client", undefined, undefined, undefined, errOrResponse);
}
else {
return new AdtErrorException(errOrResponse, properties, type, message, parent, namespace, localizedMessage, response);
}
}
constructor(err, properties, type, message, parent, namespace, localizedMessage, response) {
super();
this.err = err;
this.properties = properties;
this.type = type;
this.message = message;
this.parent = parent;
this.namespace = namespace;
this.localizedMessage = localizedMessage;
this.response = response;
}
}
exports.AdtErrorException = AdtErrorException;
// tslint:disable-next-line:max-classes-per-file
class AdtCsrfException extends Error {
get typeID() {
return CSRFEXTYPEID;
}
constructor(message, parent) {
super();
this.message = message;
this.parent = parent;
}
}
// tslint:disable-next-line:max-classes-per-file
class AdtHttpException extends Error {
get typeID() {
return HTTPEXTYPEID;
}
get code() {
const p = this.parent;
return (p.response && p.response.status) || 0;
}
get message() {
return this.parent.message;
}
get name() {
return this.parent.name;
}
constructor(parent) {
super();
this.parent = parent;
}
}
function isAdtError(e) {
return (e === null || e === void 0 ? void 0 : e.typeID) === ADTEXTYPEID;
}
function isCsrfError(e) {
return (e === null || e === void 0 ? void 0 : e.typeID) === CSRFEXTYPEID;
}
function isHttpError(e) {
return (e === null || e === void 0 ? void 0 : e.typeID) === HTTPEXTYPEID;
}
function isAdtException(e) {
return isAdtError(e) || isCsrfError(e) || isHttpError(e);
}
const isLoginError = (adtErr) => (isHttpError(adtErr) && adtErr.code === 401) || isCsrfError(adtErr);
exports.isLoginError = isLoginError;
const simpleError = (response) => adtException(`Error ${response.status}:${response.statusText}`, response.status);
const isCsrfException = (r) => (r.status === 403 && r.headers["x-csrf-token"] === "Required") ||
(r.status === 400 && r.statusText === "Session timed out"); // hack to get login refresh to work on expired sessions
const fromResponse = (data, response) => {
if (!data)
return simpleError(response);
if (data.match(/CSRF/))
return new AdtCsrfException(data);
const raw = (0, utilities_1.fullParse)(data);
const root = raw["exc:exception"];
if (!root && response.status === 401)
return simpleError(response);
const getf = (base, idx) => (base ? base[idx] : "");
const properties = {};
(0, utilities_1.xmlArray)(root, "properties", "entry").forEach((p) => {
properties[p["@_key"]] = `${p["#text"]}`
.replace(/^\s+/, "")
.replace(/\s+$/, "");
});
return new AdtErrorException(response.status, properties, root.type["@_id"], root.message["#text"], undefined, getf(root.namespace, "@_id"), getf(root.localizedMessage, "#text"));
};
exports.fromResponse = fromResponse;
const fromError = (error) => {
try {
if (isAdtError(error))
return error;
if ((0, AdtHTTP_1.isHttpClientException)(error) && error.response) {
if (error.status === 401)
return new AdtHttpException(error);
return (0, exports.fromResponse)(error.response.body, error.response);
}
if ((0, utilities_1.hasMessage)(error))
return new AdtErrorException(500, {}, "", error.message);
}
catch (error) { }
return AdtErrorException.create(500, {}, "Unknown error", `${error}`); // hopefully will never happen
};
exports.fromError = fromError;
function fromExceptionOrResponse_int(errOrResp, config) {
try {
if (isResponse(errOrResp))
return (0, exports.fromResponse)(errOrResp.body, errOrResp);
else
return (0, exports.fromError)(errOrResp);
}
catch (e) {
return isResponse(errOrResp)
? AdtErrorException.create(errOrResp, {})
: (0, exports.fromError)(e);
}
}
function fromException(errOrResp, config) {
if (isAdtException(errOrResp))
return errOrResp;
if (!isResponse(errOrResp) &&
(!(0, utilities_1.isNativeError)(errOrResp) ||
((0, utilities_1.isNativeError)(errOrResp) && !(0, AdtHTTP_1.isHttpClientException)(errOrResp))))
return AdtErrorException.create(500, {}, "Unknown error", `${errOrResp}`); // hopefully will never happen
return fromExceptionOrResponse_int(errOrResp, config);
}
function adtException(message, number = 0) {
return new AdtErrorException(number, {}, "", message);
}
function ValidateObjectUrl(url) {
if (url.match(/^\/sap\/bc\/adt\/[a-z]+\/[a-zA-Z%\$]?[\w%]+/))
return; // valid
throw new AdtErrorException(0, {}, "BADOBJECTURL", "Invalid Object URL:" + url);
}
function ValidateStateful(h) {
if (h.isStateful)
return;
throw new AdtErrorException(0, {}, "STATELESS", "This operation can only be performed in stateful mode");
}
const validateParseResult = (parseResult) => {
if ((0, These_1.isLeft)(parseResult)) {
const messages = io_ts_reporters_1.default.report(parseResult);
throw adtException(messages.slice(0, 3).join("\n"));
}
return parseResult.right;
};
exports.validateParseResult = validateParseResult;
const isErrorMessageType = (x) => !!`${x}`.match(/^[EAX]$/i);
exports.isErrorMessageType = isErrorMessageType;