UNPKG

bugsplat

Version:
154 lines 6.07 kB
import { validateResponseBody, } from './bugsplat-response'; export function createStandardizedCallStack(error) { if (!error.stack?.includes('Error:')) { return `Error: ${error.message}\n${error.stack}`; } return error.stack; } export async function tryParseResponseJson(response) { let parsed; try { parsed = await response.json(); } catch { parsed = {}; } return parsed; } const isError = (val) => Boolean(val?.stack); function isFileRef(data) { return typeof data === 'object' && data !== null && typeof data.uri === 'string'; } export function appendAttachment(body, attachment) { const { filename, data } = attachment; if (data instanceof Uint8Array) { body.append(filename, new Blob([data]), filename); return; } if (isFileRef(data)) { body.append(filename, { uri: data.uri, type: data.type, name: filename }, filename); return; } body.append(filename, data, filename); } export class BugSplat { database; application; version; _formData = () => new FormData(); _fetch = globalThis.fetch.bind(globalThis); _appKey = ''; _attributes = {}; _description = ''; _email = ''; _user = ''; constructor(database, application, version) { this.database = database; this.application = application; this.version = version; } async post(errorToPost, options) { options = options || {}; const appKey = options.appKey || this._appKey; const user = options.user || this._user; const email = options.email || this._email; const description = options.description || this._description; const attributes = options.attributes || this._attributes; const callstack = createStandardizedCallStack(isError(errorToPost) ? errorToPost : new Error(errorToPost)); const url = this._getEnv('BUGSPLAT_CRASH_POST_URL') || `https://${this.database}.bugsplat.com/post/js/`; const body = this._formData(); body.append('database', this.database); body.append('appName', this.application); body.append('appVersion', this.version); body.append('appKey', appKey); body.append('user', user); body.append('email', email); body.append('description', description); body.append('callstack', callstack); if (Object.keys(attributes).length > 0) { body.append('attributes', JSON.stringify(attributes)); } for (const attachment of options.attachments || []) { appendAttachment(body, attachment); } console.log('BugSplat Error:', errorToPost); console.log('BugSplat Url:', url); const response = await this._fetch(url, { method: 'POST', body }); const json = await tryParseResponseJson(response); console.log('BugSplat POST status code:', response.status); console.log('BugSplat POST response body:', json); if (response.status === 400) { return this._createReturnValue(new Error('BugSplat Error: Bad request'), json, errorToPost); } if (response.status === 429) { return this._createReturnValue(new Error('BugSplat Error: Rate limit of one crash per second exceeded'), json, errorToPost); } if (!response.ok) { return this._createReturnValue(new Error('BugSplat Error: Unknown error'), json, errorToPost); } if (!validateResponseBody(json)) { return this._createReturnValue(new Error('BugSplat Error: Invalid response received'), json, errorToPost); } return this._createReturnValue(null, json, errorToPost); } async postFeedback(title, options) { options = options || {}; const appKey = options.appKey || this._appKey; const user = options.user || this._user; const email = options.email || this._email; const description = options.description || this._description; const attributes = options.attributes || this._attributes; const baseUrl = this._getEnv('BUGSPLAT_FEEDBACK_POST_URL') || `https://${this.database}.bugsplat.com/post/feedback/`; const body = this._formData(); body.append('database', this.database); body.append('appName', this.application); body.append('appVersion', this.version); body.append('title', title); body.append('appKey', appKey); body.append('user', user); body.append('email', email); body.append('description', description); if (Object.keys(attributes).length > 0) { body.append('attributes', JSON.stringify(attributes)); } for (const attachment of options.attachments || []) { appendAttachment(body, attachment); } console.log('BugSplat Feedback:', title); const response = await this._fetch(baseUrl, { method: 'POST', body }); const json = await tryParseResponseJson(response); if (!response.ok) { return this._createReturnValue(new Error('BugSplat Error: Failed to post feedback'), json, title); } if (!validateResponseBody(json)) { return this._createReturnValue(new Error('BugSplat Error: Invalid response received'), json, title); } return this._createReturnValue(null, json, title); } setDefaultAppKey(appKey) { this._appKey = appKey; } setDefaultAttributes(attributes) { this._attributes = attributes; } setDefaultDescription(description) { this._description = description; } setDefaultEmail(email) { this._email = email; } setDefaultUser(user) { this._user = user; } _getEnv(key) { return typeof process !== 'undefined' ? process.env?.[key] : undefined; } _createReturnValue(error, response, original) { return { error, response, original, }; } } //# sourceMappingURL=bugsplat.js.map