Skip to content

Commit 7ca6026

Browse files
committed
feat: catch errors internally
create custom error type
1 parent 54420e3 commit 7ca6026

File tree

3 files changed

+160
-35
lines changed

3 files changed

+160
-35
lines changed

README.md

+47-17
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,50 @@ npm install userscript-with-webdav
2020

2121
## Usage
2222

23-
When embed:
23+
Example:
2424

25-
```javascript
25+
```typescript
26+
// When embed:
2627
import Webdav from 'userscript-with-webdav';
28+
29+
(async () => {
30+
const wh = new Webdav('<webDAVURL>', '<webDAVUser>', '<webDAVPassword>');
31+
32+
// download
33+
try {
34+
const res = await wh.download('path/to/your/file');
35+
console.log('status:', res.status);
36+
console.log('data:', res.data);
37+
} catch (err) {
38+
if (err instanceof Webdav.NotFound) {
39+
console.error('file does not exist');
40+
} else if (err instanceof Webdav.Unauthorized) {
41+
console.error('authentication failed');
42+
}
43+
}
44+
45+
// upload
46+
try {
47+
await wh.upload('path/to/your/file', '<data>');
48+
} catch (err) {
49+
if (err instanceof Webdav.Forbidden) {
50+
console.error('permission error');
51+
}
52+
}
53+
})();
2754
```
2855

2956
## Type
3057

3158
```typescript
32-
class Webdav {
59+
declare class Webdav {
60+
static InternalError: typeof InternalError;
61+
static Unauthorized: typeof Unauthorized;
62+
static Forbidden: typeof Forbidden;
63+
static NotFound: typeof NotFound;
64+
static Redirection: typeof Redirection;
65+
static ClientSideError: typeof ClientSideError;
66+
static ServerSideError: typeof ServerSideError;
3367
/**
3468
* Constructor
3569
* @param domainURL WebDAV domain
@@ -38,34 +72,30 @@ class Webdav {
3872
*/
3973
constructor(domainURL?: string, user?: string, password?: string);
4074
/**
41-
* Update Config
42-
* @param domainURL WebDAV domain
43-
* @param user User name
44-
* @param password User password
75+
* Generate validation request header
76+
* @returns Verification request header
4577
*/
4678
updateConfig(domainURL: string, user: string, password: string): void;
4779
/**
4880
* Download file content
4981
* @param fileURL Relative file URL
5082
* @returns Response
5183
*/
52-
download(fileURL: string): Promise<{
53-
status: number;
54-
data: string;
55-
}>;
84+
download(fileURL: string): Promise<ConnectionResponse>;
5685
/**
5786
* Upload file content
5887
* @param fileURL Relative file URL
5988
* @param data Data
6089
* @returns Response
6190
*/
62-
upload(
63-
fileURL: string,
64-
data: string
65-
): Promise<{
91+
upload(fileURL: string, data: string): Promise<ConnectionResponse>;
92+
}
93+
94+
declare interface ConnectionResponse {
95+
/** Response status code */
6696
status: number;
67-
data: any;
68-
}>;
97+
/** Response data */
98+
data: string;
6999
}
70100
```
71101

src/common/errors.ts

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
export class InternalError extends Error {
2+
constructor(message: string) {
3+
super(message);
4+
this.name = 'InternalError';
5+
}
6+
}
7+
8+
export class Unauthorized extends Error {
9+
constructor() {
10+
super('unauthorized (401)');
11+
this.name = 'Unauthorized';
12+
}
13+
}
14+
15+
export class Forbidden extends Error {
16+
constructor() {
17+
super('forbidden (403)');
18+
this.name = 'Forbidden';
19+
}
20+
}
21+
22+
export class NotFound extends Error {
23+
constructor() {
24+
super('not found (404)');
25+
this.name = 'NotFound';
26+
}
27+
}
28+
29+
export class Redirection extends Error {
30+
constructor(code: number) {
31+
super(`redirection (${code})`);
32+
this.name = 'Redirection';
33+
}
34+
}
35+
36+
export class ClientSideError extends Error {
37+
constructor(code: number) {
38+
super(`client-side error (${code})`);
39+
this.name = 'ClientSideError';
40+
}
41+
}
42+
43+
export class ServerSideError extends Error {
44+
constructor(code: number) {
45+
super(`server-side error (${code})`);
46+
this.name = 'ServerSideError';
47+
}
48+
}

src/index.ts

+65-18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
import G from './common/gm';
2+
import { InternalError, Unauthorized, Forbidden, NotFound, Redirection, ClientSideError, ServerSideError } from './common/errors';
3+
4+
interface ConnectionResponse {
5+
/** Response status code */
6+
status: number;
7+
/** Response data */
8+
data: string;
9+
}
210

311
class Webdav {
12+
static InternalError = InternalError;
13+
static Unauthorized = Unauthorized;
14+
static Forbidden = Forbidden;
15+
static NotFound = NotFound;
16+
static Redirection = Redirection;
17+
static ClientSideError = ClientSideError;
18+
static ServerSideError = ServerSideError;
19+
420
/**
521
* Constructor
622
* @param domainURL WebDAV domain
@@ -36,6 +52,35 @@ class Webdav {
3652
return this.domainURL + fileURL;
3753
}
3854

55+
/**
56+
* Data Encapsulation
57+
* @param status status code
58+
* @param data data
59+
* @returns
60+
*/
61+
private dataEncapsulation(status: number, data: string): ConnectionResponse {
62+
if (status === -1) {
63+
throw new Webdav.InternalError('internal program error');
64+
} else if (status === 401) {
65+
throw new Webdav.Unauthorized();
66+
} else if (status === 403) {
67+
throw new Webdav.Forbidden();
68+
} else if (status === 404) {
69+
throw new Webdav.NotFound();
70+
} else if (status >= 300 && status < 400) {
71+
throw new Webdav.Redirection(status);
72+
} else if (status >= 400 && status < 500) {
73+
throw new Webdav.ClientSideError(status);
74+
} else if (status >= 500) {
75+
throw new Webdav.ServerSideError(status);
76+
}
77+
78+
return {
79+
status,
80+
data,
81+
};
82+
}
83+
3984
/**
4085
* Update Config
4186
* @param domainURL WebDAV domain
@@ -53,23 +98,24 @@ class Webdav {
5398
* @param fileURL Relative file URL
5499
* @returns Response
55100
*/
56-
async download(fileURL: string) {
101+
async download(fileURL: string): Promise<ConnectionResponse> {
57102
const headers = this.generateHeaders();
103+
let status = 0,
104+
data = '';
105+
58106
try {
59107
const res = await G.ajax(this.generateFullURL(fileURL), {
60108
method: 'GET',
61109
headers,
62110
});
63-
return {
64-
status: res.status,
65-
data: res.responseText,
66-
};
111+
status = res.status;
112+
data = res.responseText;
67113
} catch {
68-
return {
69-
status: -1,
70-
data: '',
71-
};
114+
status = -1;
115+
data = '';
72116
}
117+
118+
return this.dataEncapsulation(status, data);
73119
}
74120

75121
/**
@@ -78,24 +124,25 @@ class Webdav {
78124
* @param data Data
79125
* @returns Response
80126
*/
81-
async upload(fileURL: string, data: string) {
127+
async upload(fileURL: string, data: string): Promise<ConnectionResponse> {
82128
const headers = this.generateHeaders();
129+
let status = 0,
130+
resData = '';
131+
83132
try {
84133
const res = await G.ajax(this.generateFullURL(fileURL), {
85134
method: 'PUT',
86135
headers,
87136
data,
88137
});
89-
return {
90-
status: res.status,
91-
data: res.response,
92-
};
138+
status = res.status;
139+
resData = res.response;
93140
} catch {
94-
return {
95-
status: -1,
96-
data: null,
97-
};
141+
status = -1;
142+
resData = '';
98143
}
144+
145+
return this.dataEncapsulation(status, resData);
99146
}
100147
}
101148

0 commit comments

Comments
 (0)