store stacktrace as a json array so we can reverse it when displaying and fixed up display of errors
This commit is contained in:
parent
6fa18c53df
commit
08271da363
|
@ -1,8 +1,8 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: e0510795b643
|
||||
Revision ID: 5dae229f0a9b
|
||||
Revises:
|
||||
Create Date: 2023-04-19 14:36:11.004444
|
||||
Create Date: 2023-04-20 08:19:03.409112
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
|
@ -10,7 +10,7 @@ import sqlalchemy as sa
|
|||
from sqlalchemy.dialects import mysql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'e0510795b643'
|
||||
revision = '5dae229f0a9b'
|
||||
down_revision = None
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
@ -467,7 +467,7 @@ def upgrade():
|
|||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('process_instance_event_id', sa.Integer(), nullable=False),
|
||||
sa.Column('message', sa.String(length=1024), nullable=False),
|
||||
sa.Column('stacktrace', sa.Text(), nullable=False),
|
||||
sa.Column('stacktrace', sa.JSON(), nullable=False),
|
||||
sa.Column('task_line_number', sa.Integer(), nullable=True),
|
||||
sa.Column('task_offset', sa.Integer(), nullable=True),
|
||||
sa.Column('task_line_contents', sa.String(length=255), nullable=True),
|
|
@ -17,7 +17,7 @@ class ProcessInstanceErrorDetailModel(SpiffworkflowBaseDBModel):
|
|||
message: str = db.Column(db.String(1024), nullable=False)
|
||||
|
||||
# this should be 65k in mysql
|
||||
stacktrace: str = db.Column(db.Text(), nullable=False)
|
||||
stacktrace: Optional[list] = db.Column(db.JSON, nullable=False)
|
||||
|
||||
task_line_number: Optional[int] = db.Column(db.Integer)
|
||||
task_offset: Optional[int] = db.Column(db.Integer)
|
||||
|
|
|
@ -619,7 +619,7 @@ class TaskService:
|
|||
|
||||
if exception is not None:
|
||||
# truncate to avoid database errors on large values. We observed that text in mysql is 65K.
|
||||
stacktrace = traceback.format_exc()[0:63999]
|
||||
stacktrace = traceback.format_exc().split("\n")
|
||||
message = str(exception)[0:1023]
|
||||
|
||||
task_line_number = None
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import copy
|
||||
import time
|
||||
from spiffworkflow_backend.models.process_instance_event import ProcessInstanceEventType
|
||||
from typing import Callable
|
||||
from typing import Optional
|
||||
from typing import Set
|
||||
|
@ -329,6 +330,7 @@ class WorkflowExecutionService:
|
|||
self.process_bpmn_messages()
|
||||
self.queue_waiting_receive_messages()
|
||||
except SpiffWorkflowException as swe:
|
||||
TaskService.add_event_to_process_instance(self.process_instance_model, ProcessInstanceEventType.task_failed.value, exception=swe, task_guid=str(swe.task.id))
|
||||
raise ApiError.from_workflow_exception("task_error", str(swe), swe) from swe
|
||||
|
||||
finally:
|
||||
|
|
|
@ -34,7 +34,9 @@ export const childrenForErrorObject = (errorObject: ErrorForDisplay) => {
|
|||
);
|
||||
}
|
||||
|
||||
const message = <div>{errorObject.message}</div>;
|
||||
const message = (
|
||||
<div className={errorObject.messageClassName}>{errorObject.message}</div>
|
||||
);
|
||||
const taskName = errorDetailDisplay(errorObject, 'task_name', 'Task Name');
|
||||
const taskId = errorDetailDisplay(errorObject, 'task_id', 'Task ID');
|
||||
const fileName = errorDetailDisplay(errorObject, 'file_name', 'File Name');
|
||||
|
@ -44,14 +46,26 @@ export const childrenForErrorObject = (errorObject: ErrorForDisplay) => {
|
|||
'Line Number'
|
||||
);
|
||||
const errorLine = errorDetailDisplay(errorObject, 'error_line', 'Context');
|
||||
let taskTrace = null;
|
||||
let codeTrace = null;
|
||||
if (errorObject.task_trace && errorObject.task_trace.length > 0) {
|
||||
taskTrace = (
|
||||
codeTrace = (
|
||||
<div className="error_info">
|
||||
<span className="error_title">Call Activity Trace:</span>
|
||||
{errorObject.task_trace.reverse().join(' -> ')}
|
||||
</div>
|
||||
);
|
||||
} else if (errorObject.stacktrace) {
|
||||
codeTrace = (
|
||||
<pre className="error_info">
|
||||
<span className="error_title">Stacktrace:</span>
|
||||
{errorObject.stacktrace.reverse().map((a) => (
|
||||
<>
|
||||
{a}
|
||||
<br />
|
||||
</>
|
||||
))}
|
||||
</pre>
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
|
@ -63,7 +77,7 @@ export const childrenForErrorObject = (errorObject: ErrorForDisplay) => {
|
|||
fileName,
|
||||
lineNumber,
|
||||
errorLine,
|
||||
taskTrace,
|
||||
codeTrace,
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
@ -234,6 +234,8 @@ export type HotCrumbItem = HotCrumbItemArray | HotCrumbItemObject;
|
|||
|
||||
export interface ErrorForDisplay {
|
||||
message: string;
|
||||
|
||||
messageClassName?: string;
|
||||
sentry_link?: string;
|
||||
task_name?: string;
|
||||
task_id?: string;
|
||||
|
@ -241,6 +243,7 @@ export interface ErrorForDisplay {
|
|||
error_line?: string;
|
||||
file_name?: string;
|
||||
task_trace?: string[];
|
||||
stacktrace?: string[];
|
||||
}
|
||||
|
||||
export interface AuthenticationParam {
|
||||
|
@ -301,7 +304,7 @@ export interface JsonSchemaForm {
|
|||
export interface ProcessInstanceEventErrorDetail {
|
||||
id: number;
|
||||
message: string;
|
||||
stacktrace: string;
|
||||
stacktrace: string[];
|
||||
task_line_contents?: string;
|
||||
task_line_number?: number;
|
||||
task_offset?: number;
|
||||
|
|
|
@ -160,21 +160,16 @@ export default function ProcessInstanceLogList({ variant }: OwnProps) {
|
|||
if (eventErrorDetails) {
|
||||
const errorForDisplay: ErrorForDisplay = {
|
||||
message: eventErrorDetails.message,
|
||||
messageClassName: 'failure-string',
|
||||
task_name: eventForModal.task_definition_name,
|
||||
task_id: eventForModal.task_definition_identifier,
|
||||
line_number: eventErrorDetails.task_line_number,
|
||||
error_line: eventErrorDetails.task_line_contents,
|
||||
task_trace: eventErrorDetails.task_trace,
|
||||
stacktrace: eventErrorDetails.stacktrace,
|
||||
};
|
||||
const errorChildren = childrenForErrorObject(errorForDisplay);
|
||||
// <pre>{eventErrorDetails.stacktrace}</pre>
|
||||
errorMessageTag = (
|
||||
<>
|
||||
<p className="failure-string">{eventErrorDetails.message}</p>
|
||||
<br />
|
||||
{errorChildren}
|
||||
</>
|
||||
);
|
||||
errorMessageTag = <>{errorChildren}</>;
|
||||
}
|
||||
return (
|
||||
<Modal
|
||||
|
@ -207,8 +202,8 @@ export default function ProcessInstanceLogList({ variant }: OwnProps) {
|
|||
failureCallback: (error: any) => {
|
||||
const errorObject: ProcessInstanceEventErrorDetail = {
|
||||
id: 0,
|
||||
message: `ERROR: ${error.message}`,
|
||||
stacktrace: '',
|
||||
message: `ERROR retrieving error details: ${error.message}`,
|
||||
stacktrace: [],
|
||||
};
|
||||
setEventErrorDetails(errorObject);
|
||||
},
|
||||
|
@ -218,7 +213,7 @@ export default function ProcessInstanceLogList({ variant }: OwnProps) {
|
|||
|
||||
const eventTypeCell = (logEntry: ProcessInstanceLogEntry) => {
|
||||
if (
|
||||
['process_instance_error', 'task_error'].includes(logEntry.event_type)
|
||||
['process_instance_error', 'task_failed'].includes(logEntry.event_type)
|
||||
) {
|
||||
const errorTitle = 'Event has an error';
|
||||
const errorIcon = (
|
||||
|
|
Loading…
Reference in New Issue