Skip to content

Commit

Permalink
add hook(useBoundary)
Browse files Browse the repository at this point in the history
  • Loading branch information
xyhxx committed Jul 6, 2022
1 parent 27b9e65 commit eb2e225
Show file tree
Hide file tree
Showing 23 changed files with 135 additions and 27 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,18 @@ import FallbackComponent, from './fallback.vue';
You can view the examples used with suspend+vue-query in the
[codesandbox](https://codesandbox.io/s/pcmg9e)

## useBoundary

It is not necessary to obtain reset and error through props,more convenient to use hook.

```ts

const {error, reset} = useBoundary();
console.log(error?.message, error?.name);
...

```

# Devtools

Support Vue devtools.You can view the error information and other contents in the developer tool.
Expand Down
2 changes: 1 addition & 1 deletion __tests__/capture.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils';

import { describe, test, beforeEach, expect } from 'vitest';
import ClickThrow from './components/click.vue';
import Caputre from './components/capture.vue';
import ErrorBoundary, { ErrorBoundaryProps } from '@src';
Expand Down
2 changes: 1 addition & 1 deletion __tests__/components/capture.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defineProps<{

<template>
<p id="error">{{ error.name }},{{ error.message }}</p>
<button @click="reset" id="reset">Reset</button>
<button id="reset" @click="reset">Reset</button>
</template>

<script lang="ts">
Expand Down
8 changes: 7 additions & 1 deletion __tests__/components/click.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@ function throwError() {
</script>

<template>
<button @click="throwError" id="throw">throw error</button>
<button id="throw" @click="throwError">throw error</button>
</template>

<script lang="ts">
export default {
name: 'ClickTestComponent',
};
</script>
16 changes: 16 additions & 0 deletions __tests__/components/hook.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script setup lang="ts">
import { useBoundary } from '@src';
const { reset, error } = useBoundary();
</script>

<template>
<p id="error_info">{{ error?.message ?? '' }}</p>
<button id="reset_btn" @click="reset">reset</button>
</template>

<script lang="ts">
export default {
name: 'HookTestComponent',
};
</script>
4 changes: 2 additions & 2 deletions __tests__/components/network.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { useQuery } from 'vue-query';
import axios from 'axios';
const props = defineProps<{ returnError: boolean }>();
const { data, suspense } = useQuery(
Expand All @@ -17,9 +18,8 @@ const { data, suspense } = useQuery(
if (data.status === 'success') {
return data.data;
} else {
throw new Error(data.data);
}
throw new Error(data.data);
},
{ retry: false },
);
Expand Down
2 changes: 1 addition & 1 deletion __tests__/components/refError.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function throwError() {
</script>

<template>
<button @click="throwError" id="ref_error">ref error</button>
<button id="ref_error" @click="throwError">ref error</button>
</template>

<script lang="ts">
Expand Down
2 changes: 1 addition & 1 deletion __tests__/components/typeError.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function throwError() {
</script>

<template>
<button @click="throwError" id="type_error">type error</button>
<button id="type_error" @click="throwError">type error</button>
</template>

<script lang="ts">
Expand Down
1 change: 1 addition & 0 deletions __tests__/define.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ErrorBoundary from '@src';
import { describe, test, expect } from 'vitest';

describe('VueErrorBoundary is define', function () {
test('VueErrorBoundary is define', function () {
Expand Down
1 change: 1 addition & 0 deletions __tests__/emits.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ClickThrow from './components/click.vue';
import Caputre from './components/capture.vue';
import { mount } from '@vue/test-utils';
import { defineComponent, h } from 'vue';
import { describe, test, expect } from 'vitest';

const App = defineComponent({
emits: ['captured'],
Expand Down
44 changes: 44 additions & 0 deletions __tests__/hook.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { describe, test, beforeEach, expect } from 'vitest';
import HookTest from './components/hook.vue';
import ClickTest from './components/click.vue';
import { h, defineComponent } from 'vue';
import { mount } from '@vue/test-utils';
import ErrorBoundary from '@src';

let App: any;

beforeEach(function () {
App = defineComponent({
setup() {
return function () {
return h(
ErrorBoundary,
{},
{
default: () => h(ClickTest),
fallback: () => h(HookTest),
},
);
};
},
});
});

describe('useBoundary hook', function () {
test('error info', async function () {
const app = mount(App);

let throwBtn = app.get('#throw');
await throwBtn.trigger('click');

const error = app.find('#error_info');
expect(error.exists()).toBe(true);
expect(error.text()).toBe('throwError');

const resetBtn = app.get('#reset_btn');
await resetBtn.trigger('click');

const throwBtn2 = app.find('#throw');
expect(throwBtn2.exists()).toBe(true);
});
});
2 changes: 2 additions & 0 deletions __tests__/includeAndExclude.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
/* eslint-disable vue/require-default-prop */
import ErrorBoundary, { ErrorBoundaryProps, VueErrorBoundaryEmit } from '@src';
import ClickThrow from './components/click.vue';
import Caputre from './components/capture.vue';
import ClickTypeError from './components/typeError.vue';
import ClickRefError from './components/refError.vue';
import { mount } from '@vue/test-utils';
import { defineComponent, h } from 'vue';
import { describe, test, beforeEach, expect } from 'vitest';

let App: any;

Expand Down
10 changes: 6 additions & 4 deletions __tests__/propagation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ClickThrow from './components/click.vue';
import Caputre from './components/capture.vue';
import { mount } from '@vue/test-utils';
import { defineComponent, h, onErrorCaptured } from 'vue';
import { describe, test, beforeEach, expect, vi } from 'vitest';

const fn = vi.fn();

Expand All @@ -12,15 +13,16 @@ describe('onErrorCaptured propagation', function () {
beforeEach(function () {
fn.mockReset();
App = defineComponent({
props: {
propagation: Boolean,
cb: Function,
},
components: {
ClickThrow,
ErrorBoundary,
Caputre,
},
props: {
propagation: Boolean,
// eslint-disable-next-line vue/require-default-prop
cb: Function,
},
setup(props) {
onErrorCaptured(function (errors) {
fn();
Expand Down
1 change: 1 addition & 0 deletions __tests__/reset.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ClickThrow from './components/click.vue';
import Caputre from './components/capture.vue';
import { mount } from '@vue/test-utils';
import { defineComponent, h } from 'vue';
import { describe, test, expect } from 'vitest';

const App = defineComponent({
setup() {
Expand Down
4 changes: 2 additions & 2 deletions __tests__/suspense.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import ErrorBoundary, { ErrorBoundaryProps } from '@src';
import { mount, config, flushPromises } from '@vue/test-utils';
import { mount, flushPromises } from '@vue/test-utils';
import { defineComponent, h, ref, Suspense } from 'vue';
import Caputre from './components/capture.vue';
import NetworkCom from './components/network.vue';
import { QueryClient } from 'vue-query';
import { vi } from 'vitest';
import { vi, describe, test, expect } from 'vitest';

const client = new QueryClient();

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "veboundary",
"description": "Simple and convenient Vue error boundary.",
"version": "1.1.0",
"version": "1.2.0",
"scripts": {
"build:ts": "vue-tsc --noEmit",
"build:umd": "vite build --mode umd",
Expand Down
29 changes: 18 additions & 11 deletions src/components/errorBoundary.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { registerDevtools, warn, refreshInspector, addTimeline } from '@utils';
import { registerDevtools, warn, refreshInspector, addTimeline, VEBOUNDARY_HOOK_KEY } from '@utils';
import {
ComponentPublicInstance,
defineComponent,
getCurrentInstance,
onErrorCaptured,
provide,
ref,
VNode,
} from 'vue';

const ids = new Set();

export type VueErrorBoundaryProps = {
propagation?: boolean;
include?: string[] | RegExp;
Expand All @@ -27,6 +26,9 @@ export type VueErrorBoundaryEmitPayload = {
info: string;
};

// record the ID used
const ids = new Set();

const ErrorBoundaryComponent = defineComponent({
name: 'VeBoundary',
inheritAttrs: false,
Expand Down Expand Up @@ -67,6 +69,19 @@ const ErrorBoundaryComponent = defineComponent({

const error = ref<Error | null>(null);
const errorInfo = ref('');
function reset() {
error.value = null;
errorInfo.value = '';

refreshInspector();
addTimeline(label);
}

// provide state for useBoundary
provide(VEBOUNDARY_HOOK_KEY, {
reset,
error,
});

registerDevtools({ error, info: errorInfo });

Expand Down Expand Up @@ -110,14 +125,6 @@ const ErrorBoundaryComponent = defineComponent({
return props.propagation;
});

function reset() {
error.value = null;
errorInfo.value = '';

refreshInspector();
addTimeline(label);
}

return function () {
return error.value === null
? slots.default?.()
Expand Down
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from '@hooks';
export { default } from './errorBoundary';
export type {
ErrorBoundaryProps,
Expand Down
13 changes: 13 additions & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { warn, VEBOUNDARY_HOOK_KEY } from '@utils';
import { inject, Ref } from 'vue';

type BoundaryState = {
error: Ref<Error | null>;
reset: () => void;
};

export function useBoundary() {
const info = inject<BoundaryState>(VEBOUNDARY_HOOK_KEY);
if (!info) warn('Please use useboundary in VeErrorBoundary');
return info as BoundaryState;
}
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './log';
export * from './key';
export * from './devtools';
1 change: 1 addition & 0 deletions src/utils/key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const VEBOUNDARY_HOOK_KEY = Symbol('veboundary');
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"skipLibCheck": true,
"types": ["vitest/globals"],
"baseUrl": "./src",
"paths": {
"@src": ["./index"],
"@components": ["./components/index"],
"@hooks": ["./hooks/index"],
"@utils": ["./utils/index"]
}
},
Expand Down
2 changes: 1 addition & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ export default defineConfig(function ({ mode }) {
},
include: ['__tests__/*.test.ts'],
environment: 'jsdom',
globals: true,
},
resolve: {
alias: {
'@src': resolve(__dirname, 'src'),
'@components': resolve(__dirname, 'src/components'),
'@utils': resolve(__dirname, 'src/utils'),
'@hooks': resolve(__dirname, 'src/hooks'),
},
},
publicDir: false,
Expand Down

0 comments on commit eb2e225

Please sign in to comment.