[error/ux] improve lisibility of RQLSyntaxError messages
authorLaurent Peuch <cortex@worlddomination.be>
Fri, 13 Dec 2019 04:44:34 +0100
changeset 874 a35ff5755d82
parent 873 3a9447ea6ebf
child 875 9aa93973fb42
[error/ux] improve lisibility of RQLSyntaxError messages This is a first step in trying to make syntax error messages more useful. For this faulty RQL: DISTINCT Any N WHERE N is Network, N type "cold water", FCC calibration_for N, FCC variables ILIKE "%conso%", FCC in_state SFCC, FC use_calibration FCC, FC in_state SFC, SFC name "wfs_finished", FC prediction_date FCB, FC nhours FCH, FCP calibration_for N, FCP variables ILIKE "%prod%", FCP in_state SFCP, FP use_calibration FCP, FP in_state SFP, SFP name "wfs_finished", FP prediction_date FPB, FP nhours FPH, MAX(FCB, FCP) < MIN(FCB + CAST(Interval,CAST (String,FCH)+" hours"), FPB + CAST(Interval,CAST(String,FPH)+" hours"))' It will turn the error message from: RQLSyntaxError: DISTINCT Any N WHERE N is Network, N type "cold water", FCC calibration_for N, FCC variables ILIKE "%conso%", FCC in_state SFCC, FC use_calibration FCC, FC in_state SFC, SFC name "wfs_finished", FC prediction_date FCB, FC nhours FCH, FCP calibration_for N, FCP variables ILIKE "%prod%", FCP in_state SFCP, FP use_calibration FCP, FP in_state SFP, SFP name "wfs_finished", FP prediction_date FPB, FP nhours FPH, MAX(FCB, FCP) < MIN(FCB + CAST(Interval,CAST(String,FCH)+" hours"), FPB + CAST(Interval,CAST(String,FPH)+" hours")); at: ('<f.3664>', 1, 414) Trying to find one of QMARK, R_TYPE, CMP_OP, 'IN' To: RQLSyntaxError: Trying to find one of QMARK, R_TYPE, CMP_OP, 'IN' in: DISTINCT Any N WHERE N is Network, N type "cold water", FCC calibration_for N, FCC variables ILIKE "%conso%", FCC in_state SFCC, FC use_calibration FCC, FC in_state SFC, SFC name "wfs_finished", FC prediction_date FCB, FC nhours FCH, FCP calibration_for N, FCP variables ILIKE "%prod%", FCP in_state SFCP, FP use_calibration FCP, FP in_state SFP, SFP name "wfs_finished", FP prediction_date FPB, FP nhours FPH, MAX(FCB, FCP) < MIN(FCB + CAST(Interval,CAST(String,FCH)+" hours"), FPB + CAST(Interval,CAST(String,FPH)+" hours")); at line 1 and column 414 around: ...n_date FPB, FP nhours FPH, MAX(FCB, FCP) < MIN(FCB + CAST(In... ^ here Similarly, for this RQL (the same but on several lines): DISTINCT Any N WHERE N is Network, N type "cold water", FCC calibration_for N, FCC variables ILIKE "%conso%", FCC in_state SFCC, FC use_calibration FCC, FC in_state SFC, SFC name "wfs_finished", FC prediction_date FCB, FC nhours FCH, FCP calibration_for N, FCP variables ILIKE "%prod%", FCP in_state SFCP, FP use_calibration FCP, FP in_state SFP, SFP name "wfs_finished", FP prediction_date FPB, FP nhours FPH, MAX(FCB, FCP) < MIN(FCB + CAST(Interval,CAST(String,FCH)+" hours"), FPB + CAST(Interval,CAST(String,FPH)+" hours")); It will turn the error message from: RQLSyntaxError: 1: DISTINCT Any N WHERE N is Network, N type "cold water", 2: FCC calibration_for N, FCC variables ILIKE "%conso%", 3: FCC in_state SFCC, FC use_calibration FCC, 4: FC in_state SFC, SFC name "wfs_finished", 5: FC prediction_date FCB, FC nhours FCH, 6: FCP calibration_for N, FCP variables ILIKE "%prod%", 7: FCP in_state SFCP, FP use_calibration FCP, 8: FP in_state SFP, SFP name "wfs_finished", 9: FP prediction_date FPB, FP nhours FPH, 10: MAX(FCB, FCP) < 11: MIN(FCB + CAST(Interval,CAST(String,FCH)+" hours"), 12: FPB + CAST(Interval,CAST(String,FPH)+" hours")); at: ('<f.3665>', 10, 4) Trying to find one of QMARK, R_TYPE, CMP_OP, 'IN' To: RQLSyntaxError: Trying to find one of QMARK, R_TYPE, CMP_OP, 'IN' in: 1: DISTINCT Any N WHERE N is Network, N type "cold water", 2: FCC calibration_for N, FCC variables ILIKE "%conso%", 3: FCC in_state SFCC, FC use_calibration FCC, 4: FC in_state SFC, SFC name "wfs_finished", 5: FC prediction_date FCB, FC nhours FCH, 6: FCP calibration_for N, FCP variables ILIKE "%prod%", 7: FCP in_state SFCP, FP use_calibration FCP, 8: FP in_state SFP, SFP name "wfs_finished", 9: FP prediction_date FPB, FP nhours FPH, 10: MAX(FCB, FCP) < 11: MIN(FCB + CAST(Interval,CAST(String,FCH)+" hours"), 12: FPB + CAST(Interval,CAST(String,FPH)+" hours")); at line 10 and column 4 around: MAX(FCB, FCP) < ^ here Closes #17256169
rql/__init__.py
--- a/rql/__init__.py	Thu Nov 07 18:28:41 2019 +0100
+++ b/rql/__init__.py	Fri Dec 13 04:44:34 2019 +0100
@@ -229,7 +229,28 @@
                         for idx, line in enumerate(multi_lines_rql)
                     )
 
-                msg = '%s\nat: %r\n%s' % (rqlstring, ex.pos,  ex.msg)
+                padding = 30
+                _, line, column = ex.pos
+
+                rql_line = multi_lines_rql[line - 1]
+
+                if len(rql_line) <= (padding * 2):
+                    around = rql_line
+                    here_left_padding = len("around: ") + column
+                elif column < padding:
+                    around = rql_line[:padding * 2] + "..."
+                    here_left_padding = len("around: ") + column
+                elif (len(rql_line) - padding) < column:
+                    around = "..." + rql_line[-(padding * 2):]
+                    here_left_padding = len("around: ...") + (column - (len(rql_line) - (padding * 2)))
+                else:
+                    around = "..." + rql_line[column - padding:column + padding] + "..."
+                    here_left_padding = len("around: ...") + padding
+
+                here = ' ' * (here_left_padding - 1) + '^ here'
+                msg = '%s in:\n%s\n\nat line %s and column %s\naround: %s\n%s' % (
+                    ex.msg, rqlstring, line, column, around, here
+                )
             else:
                 msg = '%s\n%s' % (rqlstring, ex.msg)
             exc = RQLSyntaxError(msg)