Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 555x 555x 555x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 534x 534x 534x 534x 534x 837x 837x 185x 185x 652x 652x 652x 652x 652x 652x 652x 652x 652x 652x 652x 652x 652x 790x 854x 854x 854x 555x 555x 555x 299x 854x 2x 6x 6x 6x 6x 6x 2x 2x 297x 297x 798x 183x 183x 854x 652x 652x 534x 534x 534x 534x 534x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 182x 182x 182x 182x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 134x 445x 445x 445x 445x 445x 445x 445x 445x 445x 445x 445x 445x 445x 445x 134x 134x 134x | /**
* WikiLambda Vue editor: Error handling utils
*
* @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt
* @license MIT
*/
'use strict';
const Constants = require( '../Constants.js' );
const { hybridToCanonical } = require( './schemata.js' );
const { isLocalKey, isValidZidFormat } = require( './typeUtils.js' );
const errorUtils = {
/**
* Returns the global key that identifies an error value key.
* The value of an error is an instance of the generic type Z885/Errortype to
* type, so its keys can arrive in local form (K1, K2…). The labels are stored
* with the global keys of the error type (Z592K1, Z592K2…), so add the error
* type to the local keys. Keys that are already global stay unchanged.
*
* @param {string} key
* @param {string|Object} errorType
* @return {string}
*/
getGlobalErrorKey: function ( key, errorType ) {
return ( isLocalKey( key ) && isValidZidFormat( errorType ) ) ?
`${ errorType }${ key }` :
key;
},
/**
* Extract error information and nested error children form a parent error/Z5 object.
* Returns an object with the following structure/error description:
* * errorType: zid of the error type/Z50 object
* * errorMessage: string built with the error type label and the string arguments
* * children: nested errors found in the error value
* * stringArgs: string arguments found in the error value, with their keys
* in global form (Z592K1) even if the error value uses local keys (K1)
* Children contains an array which can have zero or N items of this same structure.
*
* @param {Object} zobject
* @return {Array} of objects
*/
extractErrorData: function ( zobject ) {
/**
* @param {Object} error object
* @return {Object|undefined}
*/
const extractNestedErrors = ( error ) => {
// If this object is null or not an error; exit
if ( !error || error.Z1K1 !== Constants.Z_ERROR ) {
return undefined;
}
// Gather error type from Z5K1/error type
const errorType = error[ Constants.Z_ERROR_TYPE ];
// Gather keys from Z5K2/value, excluding Z1K1
const errorKeys = Object
.keys( error[ Constants.Z_ERROR_VALUE ] )
.filter( ( key ) => key !== Constants.Z_OBJECT_TYPE );
// Gather string arguments and nested errors separately, and ignore all the rest
const stringArgs = [];
const children = [];
for ( const key of errorKeys ) {
const value = error[ Constants.Z_ERROR_VALUE ][ key ];
// value is a string: add it to string arguments
if ( typeof value === 'string' ) {
stringArgs.push( { key: errorUtils.getGlobalErrorKey( key, errorType ), value } );
continue;
}
// value is an array of errors: extract nested errors for each one
if ( Array.isArray( value ) && value[ 0 ] === Constants.Z_ERROR ) {
for ( const item of value.slice( 1 ) ) {
const suberrorItem = extractNestedErrors( item );
if ( suberrorItem ) {
children.push( suberrorItem );
}
}
continue;
}
// else; extract nested error
const suberror = extractNestedErrors( value );
if ( suberror ) {
children.push( suberror );
}
}
return { errorType, children, stringArgs };
};
// Canonicalize whole error (just in case) before extracting its data
const canonicalError = hybridToCanonical( zobject );
return extractNestedErrors( canonicalError );
},
/**
* Extract the data of every warning/Z5 raised by a function call, given
* the value of the 'warnings' key of its metadata. This value is a typed
* list of errors: the first item gives the type of the list, so this
* method removes it. This method also removes each item that is not a
* well formed error.
*
* @param {Mixed} value
* @return {Array} of objects, with the structure returned by extractErrorData
*/
extractWarningsData: function ( value ) {
const warnings = Array.isArray( value ) ? value.slice( 1 ) : [ value ];
return warnings
.map( ( warning ) => errorUtils.extractErrorData( warning ) )
.filter( ( data ) => !!data );
},
/**
* Sanitize a string for safe HTML rendering.
* Escapes dangerous characters for HTML injection: & < > " ' / ` =
* Safer than DOM cleanup option.
*
* @param {string} input
* @return {string}
*/
escapeHtml: function ( input ) {
if ( input === null || input === undefined ) {
return '';
}
const s = ( typeof input === 'string' ) ? input : String( input );
const replacement = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/',
'`': '`',
'=': '='
};
return s.replace( /[&<>"'`=/]/g, ( char ) => replacement[ char ] );
}
};
module.exports = errorUtils;
|