diff --git a/packages/vue-cli-plugin-uni/lib/chain-webpack.js b/packages/vue-cli-plugin-uni/lib/chain-webpack.js index 1ff13f2417b20007ce09152f715e6a551a54c960..a0b5dcdc1dfc4e3ac5202408d1e585c194b5039e 100644 --- a/packages/vue-cli-plugin-uni/lib/chain-webpack.js +++ b/packages/vue-cli-plugin-uni/lib/chain-webpack.js @@ -104,9 +104,23 @@ module.exports = function chainWebpack (platformOptions, vueOptions, api) { if (runByHBuilderX) { // 由 HBuilderX 运行时,移除进度,错误 webpackConfig.plugins.delete('progress') webpackConfig.plugins.delete('friendly-errors') + } else { + webpackConfig.plugin('friendly-errors') + .tap(args => { + if (global.__error_reporting__) { + args[0].onErrors = function (severity, errors) { + if (severity !== 'error') { + return + } + const error = errors[0] + global.__error_reporting__ && global.__error_reporting__(error.name, error.message || '') + } + } + return args + }) } if (process.env.BUILD_ENV === 'ali-ide') { webpackConfig.plugins.delete('progress') } } -} +} diff --git a/packages/vue-cli-plugin-uni/lib/env.js b/packages/vue-cli-plugin-uni/lib/env.js index 3d49f26cb5880b7461b86176e9a1cffde058d9ec..5cbfa1f1794eb88a357e000260a1732a41866d4d 100644 --- a/packages/vue-cli-plugin-uni/lib/env.js +++ b/packages/vue-cli-plugin-uni/lib/env.js @@ -2,6 +2,8 @@ const fs = require('fs') const path = require('path') const mkdirp = require('mkdirp') const loaderUtils = require('loader-utils') + +require('./error-reporting') const hasOwnProperty = Object.prototype.hasOwnProperty diff --git a/packages/vue-cli-plugin-uni/lib/error-reporting.js b/packages/vue-cli-plugin-uni/lib/error-reporting.js new file mode 100644 index 0000000000000000000000000000000000000000..fb1c3e068e5ea04131cfb67ed8fec99cbb464428 --- /dev/null +++ b/packages/vue-cli-plugin-uni/lib/error-reporting.js @@ -0,0 +1,44 @@ +function shouldReport (err = '') { + try { + const errMsg = err.toString() + // 目前简单的上报逻辑为:错误信息中包含@dcloudio包名 + if ( + errMsg.includes('@dcloudio') && + !errMsg.includes('Errors compiling template') + ) { + return true + } + } catch (e) {} + return false +} + +// err:string|Error +function report (type, err) { + if (shouldReport(err)) { + console.log('Error Reporting...') + // const https = require('https') + // const data = ... + // const req = https.request({ + // hostname: '', + // port: 8080, + // path: '/todos', + // method: 'POST', + // headers: { + // 'Content-Type': 'application/json', + // 'Content-Length': data.length + // } + // }) + // req.write(data) + // req.end() + } +} + +global.__error_reporting__ = report + +process + .on('unhandledRejection', (reason, p) => { + global.__error_reporting__ && global.__error_reporting__('unhandledRejection', reason) + }) + .on('uncaughtException', err => { + global.__error_reporting__ && global.__error_reporting__('uncaughtException', err) + }) diff --git a/packages/vue-cli-plugin-uni/util/on-errors.js b/packages/vue-cli-plugin-uni/util/on-errors.js index c47019d8e14f51cff43f97aeacf8bd0e9db730f2..234479848f2f3ca721d7378a6aef91fe51eb79af 100644 --- a/packages/vue-cli-plugin-uni/util/on-errors.js +++ b/packages/vue-cli-plugin-uni/util/on-errors.js @@ -1,4 +1,10 @@ const stringify = require('./stringify') module.exports = function (errors) { - console.error(stringify(errors)) + const errMsg = stringify(errors, 'error') + if (typeof errMsg !== 'string') { + global.__error_reporting__ && global.__error_reporting__(errMsg.type, errMsg.msg) + console.error(errMsg.msg) + } else { + console.error(errMsg) + } } diff --git a/packages/vue-cli-plugin-uni/util/stringify.js b/packages/vue-cli-plugin-uni/util/stringify.js index 7f5598ddc7fcf696dee35cd2ddfe835404593797..4ef5d544ba9e555805c8d90494fdb0ece02c44c7 100644 --- a/packages/vue-cli-plugin-uni/util/stringify.js +++ b/packages/vue-cli-plugin-uni/util/stringify.js @@ -2,16 +2,17 @@ const path = require('path') const formatErrors = require('./format-errors') -module.exports = function stringify (errors) { - return (Array.from( +module.exports = function stringify (errors, type) { + let hasUnknownErr = false + const msg = Array.from( new Set( errors.map(err => { const formatError = formatErrors[err.name] - if (formatError) { const result = formatError(err) if (result) { if (typeof result === 'string') { + hasUnknownErr = true return result } else { if (err.module.resource) { @@ -26,11 +27,20 @@ module.exports = function stringify (errors) { } else if (result === false) { return '' // skip } + } else { + hasUnknownErr = true } return err.message }) ) - ) - .filter(msg => !!msg) - .join('\n')) + ).filter(msg => !!msg).join('\n') + + if (type === 'error' && hasUnknownErr) { + return { + type: 'onErrors', + msg + } + } + + return msg }