✨ back,front: report client errors to the server (#714)
This commit is contained in:
committed by
Anton Shepilov
parent
b04f64a2b0
commit
ea8fc2e2f1
@@ -36,6 +36,7 @@ import { formatCompany, getCompanyStats } from "../utils";
|
|||||||
import { formatUser } from "../../../utils/users";
|
import { formatUser } from "../../../utils/users";
|
||||||
import gr from "../../global-resolver";
|
import gr from "../../global-resolver";
|
||||||
import config from "config";
|
import config from "config";
|
||||||
|
import { getLogger } from "../../../core/platform/framework";
|
||||||
|
|
||||||
export class UsersCrudController
|
export class UsersCrudController
|
||||||
implements
|
implements
|
||||||
@@ -93,6 +94,30 @@ export class UsersCrudController
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** This allows a logged in user to upload log entries */
|
||||||
|
async reportClientLog(
|
||||||
|
request: FastifyRequest<{ Body: { [key: string]: string } }>,
|
||||||
|
): Promise<object> {
|
||||||
|
const headers = { ...request.headers };
|
||||||
|
const boringOrSecretHeaders =
|
||||||
|
"cookie authorization cache-control connection pragma content-length content-type accept accept-encoding accept-language".split(
|
||||||
|
/\s+/g,
|
||||||
|
);
|
||||||
|
boringOrSecretHeaders.forEach(header => delete headers[header]);
|
||||||
|
const message =
|
||||||
|
request.body.message ||
|
||||||
|
"(missing message property in UsersCrudController.reportClientLog request body)";
|
||||||
|
delete request.body.message;
|
||||||
|
getLogger("FromBrowser").error(
|
||||||
|
{
|
||||||
|
headers,
|
||||||
|
...request.body,
|
||||||
|
},
|
||||||
|
message,
|
||||||
|
);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
async setPreferences(
|
async setPreferences(
|
||||||
request: FastifyRequest<{ Body: User["preferences"] }>,
|
request: FastifyRequest<{ Body: User["preferences"] }>,
|
||||||
): Promise<User["preferences"]> {
|
): Promise<User["preferences"]> {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
getUserSchema,
|
getUserSchema,
|
||||||
getUsersSchema,
|
getUsersSchema,
|
||||||
postDevicesSchema,
|
postDevicesSchema,
|
||||||
|
sendUserClientReportSchema,
|
||||||
setUserPreferencesSchema,
|
setUserPreferencesSchema,
|
||||||
} from "./schemas";
|
} from "./schemas";
|
||||||
|
|
||||||
@@ -52,6 +53,15 @@ const routes: FastifyPluginCallback = (fastify: FastifyInstance, options, next)
|
|||||||
handler: usersController.setPreferences.bind(usersController),
|
handler: usersController.setPreferences.bind(usersController),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fastify.route({
|
||||||
|
method: "POST",
|
||||||
|
url: `${usersUrl}/me/reportLog`,
|
||||||
|
preHandler: accessControl,
|
||||||
|
preValidation: [fastify.authenticate],
|
||||||
|
schema: sendUserClientReportSchema,
|
||||||
|
handler: usersController.reportClientLog.bind(usersController),
|
||||||
|
});
|
||||||
|
|
||||||
fastify.route({
|
fastify.route({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: `${usersUrl}/me`,
|
url: `${usersUrl}/me`,
|
||||||
|
|||||||
@@ -191,6 +191,19 @@ export const setUserPreferencesSchema = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const sendUserClientReportSchema = {
|
||||||
|
request: {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
message: { type: "string" },
|
||||||
|
},
|
||||||
|
required: ["message"],
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
"2xx": {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const getUsersSchema = {
|
export const getUsersSchema = {
|
||||||
type: "object",
|
type: "object",
|
||||||
properties: {
|
properties: {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import CurrentUser from '../../../deprecated/user/CurrentUser';
|
|||||||
import { setUserList } from '../hooks/use-user-list';
|
import { setUserList } from '../hooks/use-user-list';
|
||||||
import Logger from 'features/global/framework/logger-service';
|
import Logger from 'features/global/framework/logger-service';
|
||||||
import { UserQuota } from "features/users/types/user-quota";
|
import { UserQuota } from "features/users/types/user-quota";
|
||||||
|
import version from '../../../environment/version';
|
||||||
|
|
||||||
export type SearchContextType = {
|
export type SearchContextType = {
|
||||||
scope: 'company' | 'workspace' | 'all';
|
scope: 'company' | 'workspace' | 'all';
|
||||||
@@ -142,6 +143,30 @@ class UserAPIClientService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Send log entry to the server's logs. Try to include a `message` property please */
|
||||||
|
async reportLog(body: any | { message: string, error?: Error, err?: Error, e?: Error, }): Promise<void> {
|
||||||
|
const actualBody = {
|
||||||
|
version: version.version_detail || version.version,
|
||||||
|
...body,
|
||||||
|
} as any;
|
||||||
|
for (const [key, val] of Object.entries(actualBody)) {
|
||||||
|
const error = val as Error;
|
||||||
|
if ((error as Error).stack) {
|
||||||
|
actualBody[key] = {
|
||||||
|
message: error.message,
|
||||||
|
stack: error.stack,
|
||||||
|
error,
|
||||||
|
};
|
||||||
|
if (!actualBody.message) actualBody.message = "Error: " + error.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!actualBody.message) actualBody.message = "(missing message property in UserAPIClient.reportLog)";
|
||||||
|
return Api.post<object, {}>(
|
||||||
|
'/internal/services/users/v1/users/me/reportLog',
|
||||||
|
actualBody,
|
||||||
|
).then(result => undefined);
|
||||||
|
}
|
||||||
|
|
||||||
async getQuota(companyId: string, userId: string): Promise<UserQuota> {
|
async getQuota(companyId: string, userId: string): Promise<UserQuota> {
|
||||||
return Api.get<UserQuota>(
|
return Api.get<UserQuota>(
|
||||||
`/internal/services/users/v1/users/${userId}/quota?companyId=${companyId}`,
|
`/internal/services/users/v1/users/${userId}/quota?companyId=${companyId}`,
|
||||||
@@ -255,4 +280,10 @@ class UserAPIClientService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const UserAPIClient = new UserAPIClientService();
|
const UserAPIClient = new UserAPIClientService();
|
||||||
|
|
||||||
|
window.onerror = (message, url, line, col, error) => {
|
||||||
|
UserAPIClient.reportLog({ message, url, line, col, error });
|
||||||
|
return false; // don't suppress normal alert
|
||||||
|
}
|
||||||
|
|
||||||
export default UserAPIClient;
|
export default UserAPIClient;
|
||||||
|
|||||||
Reference in New Issue
Block a user