client/routes/workflow/stack-trace.vue (141 lines of code) (raw):

<script> // Copyright (c) 2017-2024 Uber Technologies Inc. // Portions of the Software are attributed to Copyright (c) 2020-2024 Temporal Technologies Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import { getQueryResult } from './helpers'; import { getDatetimeFormattedString } from '~helpers'; import { httpService } from '~services'; export default { data() { return { loading: undefined, stackTrace: undefined, stackTraceTimestamp: undefined, }; }, props: [ 'baseAPIURL', 'clusterName', 'dateFormat', 'isWorkerRunning', 'taskListName', 'timeFormat', 'timezone', ], computed: { formattedStackTraceTimestamp() { const { dateFormat, stackTraceTimestamp, timeFormat, timezone } = this; return stackTraceTimestamp ? getDatetimeFormattedString({ date: stackTraceTimestamp, dateFormat, timeFormat, timezone, }) : ''; }, }, created() { if (!this.isWorkerRunning) { return; } this.getStackTrace(); }, methods: { getStackTrace() { this.loading = true; return httpService .post(`${this.baseAPIURL}/query/__stack_trace`) .then(({ queryResult }) => { this.stackTrace = getQueryResult(queryResult); this.stackTraceTimestamp = new Date(); }) .catch(e => { // eslint-disable-next-line no-console console.error(e); this.stackTrace = { error: (e.json && e.json.message) || e.status || e.message, }; }) .finally(() => { this.loading = false; }); }, }, watch: { isWorkerRunning: function(newVal, oldVal) { if (newVal == false) { this.queries = []; return; } this.getStackTrace(); }, }, }; </script> <template> <section :class="{ 'stack-trace': true, loading }" data-cy="stack-trace"> <header v-if="stackTraceTimestamp"> <span>Stack trace at {{ formattedStackTraceTimestamp }}</span> <a href="#" class="refresh" @click="getStackTrace">Refresh</a> </header> <pre v-if="stackTrace && stackTrace.payloads !== undefined" class="stack-trace-view" >{{ stackTrace.payloads }}</pre > <span class="error" v-if="stackTrace && stackTrace.error"> {{ stackTrace.error }} </span> <span v-if="!isWorkerRunning" class="no-queries"> There are no Workers currently listening to the Task List: <router-link :to="{ name: 'task-list', params: { clusterName, taskList: taskListName, }, }" >{{ taskListName }} </router-link> </span> </section> </template> <style lang="stylus"> @require "../../styles/definitions.styl" section.stack-trace padding layout-spacing-small header margin-bottom layout-spacing-medium a.refresh margin 0 1em action-button() icon-refresh() section .stack-trace-view white-space pre-wrap span.no-queries { display: block; width: 100%; text-align: center; font-size: 20px; color: uber-black-60; } </style>