fix(frontend): correct time adjustment for resources+merge with payloads by name + show body only if present

This commit is contained in:
Alex Kaminskii 2022-12-12 15:39:51 +01:00
parent b819e86945
commit 6054aef8e5
6 changed files with 29 additions and 25 deletions

View file

@ -153,10 +153,12 @@ function NetworkPanel() {
const activeTab = devTools[INDEX_KEY].activeTab;
const activeIndex = devTools[INDEX_KEY].index;
const list = useMemo(() =>
const list = useMemo(() =>
// TODO: better merge (with body size info)
resourceList.filter(res => !fetchList.some(ft => {
if (res.url !== ft.url) { return false }
if (Math.abs(res.time - ft.time) > 200) { return false } // TODO: find good epsilons
// res.url !== ft.url doesn't work on relative URLs appearing within fetchList (to-fix in player)
if (res.name !== ft.name) { return false }
if (Math.abs(res.time - ft.time) > 150) { return false } // TODO: find good epsilons
if (Math.abs(res.duration - ft.duration) > 100) { return false }
return true
}))

View file

@ -22,15 +22,17 @@ function FetchTabs(props: Props) {
const onTabClick = (tab: string) => setActiveTab(tab);
const [jsonRequest, setJsonRequest] = useState<Object | string | null>(null);
const [jsonResponse, setJsonResponse] = useState<Object | string | null>(null);
const [requestHeaders, setRequestHeaders] = useState(null);
const [responseHeaders, setResponseHeaders] = useState(null);
const [requestHeaders, setRequestHeaders] = useState<Record<string,string> | null>(null);
const [responseHeaders, setResponseHeaders] = useState<Record<string,string> | null>(null);
useEffect(() => {
const { request, response } = resource;
try {
let jRequest = JSON.parse(request)
setRequestHeaders(jRequest.headers);
if (typeof jRequest.headers === "object") {
setRequestHeaders(jRequest.headers);
}
try {
let jBody = JSON.parse(jRequest.body)
jBody = isValidJSON(jBody) ? jBody : jRequest.body
@ -42,7 +44,9 @@ function FetchTabs(props: Props) {
try {
let jResponse = JSON.parse(response)
setResponseHeaders(jResponse.headers);
if (typeof jResponse.headers === "object") {
setResponseHeaders(jResponse.headers);
}
try {
let jBody = JSON.parse(jResponse.body)
jBody = isValidJSON(jBody) ? jBody : jResponse.body
@ -66,13 +70,13 @@ function FetchTabs(props: Props) {
</div>
}
size="small"
show={!request}
show={!jsonRequest}
// animatedIcon="no-results"
>
<div>
<div className="mt-6">
{ !isValidJSON(jsonRequest) ? (
<div className="ml-3 break-words my-3"> {jsonRequest || request} </div>
<div className="ml-3 break-words my-3"> {jsonRequest} </div>
) : (
<JSONTree src={jsonRequest} collapsed={false} enableClipboard />
)}
@ -91,13 +95,13 @@ function FetchTabs(props: Props) {
</div>
}
size="small"
show={!response}
show={!jsonResponse}
// animatedIcon="no-results"
>
<div>
<div className="mt-6">
{ !isValidJSON(jsonResponse) ? (
<div className="ml-3 break-words my-3"> {jsonResponse || response} </div>
<div className="ml-3 break-words my-3"> {jsonResponse} </div>
) : (
<JSONTree src={jsonResponse} collapsed={false} enableClipboard />
)}

View file

@ -4,8 +4,8 @@ import stl from './headers.module.css';
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
interface Props {
requestHeaders: any;
responseHeaders: any;
requestHeaders: Record<string,string>
responseHeaders: Record<string,string>
}
function Headers(props: Props) {
return (
@ -21,7 +21,7 @@ function Headers(props: Props) {
show={!props.requestHeaders && !props.responseHeaders}
// animatedIcon="no-results"
>
{props.requestHeaders && (
{props.requestHeaders && Object.values(props.requestHeaders).length > 0 && (
<>
<div className="mb-4 mt-4">
<div className="my-2 font-medium">Request Headers</div>
@ -36,7 +36,7 @@ function Headers(props: Props) {
</>
)}
{props.responseHeaders && (
{props.responseHeaders && Object.values(props.responseHeaders).length > 0 && (
<div className="mt-4">
<div className="my-2 font-medium">Response Headers</div>
{Object.keys(props.responseHeaders).map((h) => (

View file

@ -228,9 +228,12 @@ export default class MessageManager {
let fileReadPromise = this.session.domURL && this.session.domURL.length > 0
? loadFiles(this.session.domURL, createNewParser())
: requestEFSDom(this.session.sessionId)
.then(createNewParser(false))
fileReadPromise.catch(e => {
: Promise.reject()
fileReadPromise
// EFS fallback
.catch(() => requestEFSDom(this.session.sessionId).then(createNewParser(false)))
// old url fallback
.catch(e => {
logger.error('Can not get normal session replay file:', e)
// back compat fallback to an old mobsUrl
return loadFiles(this.session.mobsUrl, createNewParser(false))

View file

@ -115,12 +115,8 @@ export default Record(
.filter(({ type, time }) => type !== TYPES.CONSOLE && time <= durationSeconds);
let resources = List(session.resources).map(Resource);
// this code shoud die.
const firstResourceTime = resources
.map((r) => r.time)
.reduce((a, b) => Math.min(a, b), Number.MAX_SAFE_INTEGER);
resources = resources
.map((r) => r.set('time', r.time - firstResourceTime))
.map((r) => r.set('time', Math.max(0, r.time - startedAt)))
.sort((r1, r2) => r1.time - r2.time);
const missedResources = resources.filter(({ success }) => !success);
@ -171,7 +167,6 @@ export default Record(
),
userDisplayName:
session.userId || session.userAnonymousId || session.userID || 'Anonymous User',
firstResourceTime,
issues: issuesList,
sessionId: sessionId || sessionID,
userId: session.userId || session.userID,

View file

@ -17,7 +17,7 @@ export function debounce(callback, wait, context = this) {
};
}
export function getResourceName(url = '') {
export function getResourceName(url: string) {
return url
.split('/')
.filter((s) => s !== '')